Lately I have been watching Pluralsight intro videos on MVC 3. I have never worked with the Model View Control approach before, but I'm starting to understand how these 3 crucial parts of an app are separated.
I created a front-end prototype of a survey I would like to implement into a View of my MVC web app. The survey is in HTML, CSS, using jQuery to deliver content changes depending on the type of evaluation (6-11 questions), and jQuery UI for a couple slider ratings.
I noticed through tutorials that you can use an HTML form and helpers that allow the user to edit content, but my prototype already allows the users to rate via radio buttons, comment text boxes, and sliders. Would I need to change any of my existing code if I just want to store this employee data to the Model, and depending on what survey's the employee has completed through the Controller, disable drop down fields?
Also, would I store the current employee data on submit of survey through an HttpPost in the Controller to the Model?
My apologies if my questions seem rather vague. Could someone point me in the right direction to a resource or documentation similar to my needs above? The Pluralsight videos are taking me in the wrong direction.
The form helpers you mentioned are optional. You could use a static HTML page in an MVC app with no issues, but it'll mean some extra work.
All the helpers are doing is rendering HTML for you to save you the trouble of handcoding it.
Your form should have a action attribute, and you can point that at an MVC controller URL. The data will arrive in your controller in the request, and you can pull the values out by hand. There are a number of ways to do this, including pulling the values out by key:
public ActionResult HelloWorld()
{
ViewData["Message"] = "Hello World!";
return View();
}
That would retrieve the value of a form input with a name="Message" attribute.
The best way to collect these values, though, is to allow ASP.NET MVC to map them to a .NET object for you. Read up on model binding to see how that works.
If you like books, I highly recommend Wrox Professional ASP.NET MVC3. It's very approachable and will cut your learning curve drastically. Good stuff.
Related
We are currently looking to experiment with modern frontend frameworks like react on an MVC4 project. We use data annotations in our models and we have a lot of forms that use unobtrusive validation on the UI.
The main thing is finding a way to use react to generate the content while still being able to make use of features like unobtrusive validation. As I understand it, it really is just a bunch of data-val attributes dynamically generated when using HTML helpers like TextAreaFor, ValidationMessageFor with the attributes getting values from the data annotations in the model classes.
I've tried several things including
ReactDOM.render(
#using (Html.BeginForm("xyz", "xyz", FormMethod.Post))
{
#Html.TextBoxFor(x => x.Email)
which results in the input box not being editable for some reason.
I'd prefer to do something more like
ReactDOM.render(
<form><input type="text" data-val="#Model.datannotations[1].val" /></form>
Is that possible? How does one get the data-val values from the model anyway? What is the best way to achieve this?
it should not be possible.
These are two differents ways to delvelop the ui.
The razor way is preprocessing the markup code in server side to fill it.
And react works in another flow using the lifecycle methods, you should have already loaded the data-anotations values for accessing it on render.
Therefore, to make this works you have to run razor engine first to fill the markup and next using react engine.
I don't recommend use this approach because it's too hard to develop on it and the developers team have to keep that flow in mind while they are developing
Note this
ReactDOM.render(<ComponentMustHaveJSX/>)
I am running a springboot application with Thymeleaf and reactJS. All the HTML text are read from message.properties by using th:text in the pages, but when I have th:text in reactJS HTML block, reactJS seems angry about it.
render() {
return (
<input type="text" th:text="#{home.welcome}">
)
}
The error is:
Namespace tags are not supported. ReactJSX is not XML.
Is there a walkaround besides using dangerouslySetInnerHTML?
Thank you!
There is no sane workaround.
You are getting this error because Thymeleaf outputs XML, and JSX parsers do not parse XML.
You did this because JSX looks very, very similar to XML. But they are very, very different, and even if you somehow hacked Thymeleaf to strip namespaced attributes and managed to get a component to render, it would be merely a fleeting moment of duct-taped-together, jury-rigged code that will fall apart under further use.
This is a really, really bad idea because JSX is Javascript. You are generating Javascript on the fly. Just to name a few reasons this will not work in the long term:
This makes your components difficult if not impossible to test.
Reasoning about application state will be a nightmare as you will struggle to figure out if the source of a certain state is coming from Thymeleaf or JS.
Your application will completely grind to a halt if Thymeleaf outputs bad JS.
These problems will all get worse with time (Thyme?) as as developers abuse the ease with which they can render server-side data to the client-side, leading to an insane application architecture.
Do not do this. Just use Thymeleaf, or just use React.
Sample Alternative: I primarily work on a React application backed by a Java backend. So I understand how someone could stumble upon this hybrid and think it might be a good idea. You are likely already using Thymeleaf and are trying to figure out how you can avoid rewriting your servlets but still get the power of React.
We were in a similar boat two years ago, except with an aging JSP frontend, but the difference is negligible. What we did (and it works well) is use a JSP page to bootstrap the entire React application. There is now one JSP page that we render to the user. This JSP page outputs JSON into a single <script> tag that contains some initial startup data that we would otherwise have to fetch immediately. This contains resources, properties, and just plain data.
We then output another <script> that points to the location of a compiled JS module containing the entire standalone React application. This application loads the JSON data once when it starts up and then makes backend calls for the rest. In some places, we have to use JSP for these, which is less than ideal but still better than your solution. What we do is have the JSP pages output a single attribute containing JSON. In this way (and with some careful pruning by our XHR library) we get a poor man's data interchange layer built atop a JSP framework we don't have time to change.
It is definitely not ideal, but it works well and we have benefited vastly from the many advantages of React. When we do have issues with this peculiar implementation, they are easy to isolate and resolve.
It is possible wrap ReactJS apps in Thymeleaf. Think if you want a static persistent part (like some links, or even just displayed data), you could use Thymeleaf. If you have a complicated part (something that requires DOM repaints, shared data, updates from UI/Sockets/whatever), you could use React.
If you need to pass state you could use Redux/other methods.
You could have your backend send data via a rest API to the React part and just render your simple parts as fragments or as whole chunks of plain HTML using Thymeleaf.
Remember, Thymeleaf is really just HTML. React is virtual DOM that renders as HTML. It's actually fairly easy to migrate one to the other. So you could write anything "Static" or that does not respond much to UI, in Thymeleaf/HTML. You could also just render those parts in React too, but without State.
Thymeleaf 3 allows you to render variables from your Java to a separate JS file. So that is also an option to pass into JSX
function showCode() {
var code = /*[[${code}]]*/ '12345';
document.getElementById('code').innerHTML = code;
}
Now you can use data- prefix attributes (ex. data-th-text="${message}").
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#support-for-html5-friendly-attribute-and-element-names
I've searched the internet for days now with no luck finding this.
My model has a property which holds a chunk of html containing Razor markup.
exmaple:
public class ViewModel
{
public string Content = "<div>#Html.TextBox(\"UserName\")</div>";
}
In the view, I display that with
#Html.Raw(Server.HtmlDecode(Model.Content).toString())
I need to be able to convert the Razor markup into html, although because the Content is dropped in through the model, the view engine doesn't process it.
I have tried simply dropping in the Content, using just .Raw(Model.Content), .Encode(Model.Content), nothing works.
Any thoughts?
You could use the RazorEngine package which allows you to parse and execute Razor code. This being said I would not recommend you giving your users the power of editing directly Razor templates. You are opening a huge security hole in your website.
There are other templating engines such as DotLiquid for example which are better suited for scenarios where you don't trust user input.
I know there is a list of similar questions but all handle pages without user interaction (static even though some js may be there).
Let's say we've a page the user can interact (e.g. svg than changes, or html tables with drilldown - content changes). Those interactions will change the page. Same happens in stackoverflow when entering the question...
The idea is adding a button, "convert to pdf" taking the state of the html and sending to the user back a pdf version (we've a Java server).
Using the print of the browser is not the answer I'm looking for :-).
Is this a stick in the moon ?
You would have to store the parameters that generate the HTML view (i.e. what the user clicks on, what selections they make, etc). If you can have a list of parameters that generate the HTML view, you can have a method which accepts the list of parameters (JSON post?), generates the HTML view and passes it to your PDF generating routine. I'm not too familiar with Java libraries for this purpose, but PHP has TCPDF can take html output to basically generate a PDF for you. Certainly, there are Java libraries which will allow you to do the same thing, or you can use the parameters to get a list of rows/arrays which can be iterated over and output using the PDF library of your choice.
Both iTextPDF and Aspose.PDF would allow you to do that (I've seen them used in two different projects), but there is no magic and you will have to do some work.
The steps are roughly:
Get (as a string) the part of the document which you want to print with jQuery or innerHTML
Call a service on the server side to convert this to PDF
[Serverside] Use a whitlist - based tool to clean up the hmtl (unless you want to be hacked). JSoup is great for that.
[Serverside] Use IText or Aspose API to create the PDF from the HTML (this is not trivial, you will have to read the doc)
Download the document
I'd also recommend DocRaptor, an HTML to PDF API built by my company, Expected Behavior.
DocRaptor uses Prince XML to generate PDFs, and thus produces higher quality results than similar products.
Adding PDF generation to your own web application using our service is as simple as making an HTTP POST request to our server.
Here's a link to DocRaptor's home page:
DocRaptor
And a link to our API documentation:
DocRaptor API documentation
What's the best way to create printable letters from an MVC application? I'm looking for sort of a mail merge thing from my app that prints a form letter with various values filled in.
In ASP.NET, I previously did this by creating an HTML document and displaying it as application/msword, but I did that with code-behind, which isn't an (easy) option in MVC, and I don't know if that's the best method or not.
Note that this is an internal application, so it can be assumed everyone has Word on their computer. With that said, it would be nice to bypass Word, but I could go either way. The simpler the better. Any ideas/methods welcome.
Since this is just HTML with the ContentType set to application/msword I can't see any reason why you would want to use code-behind.
A standard MVC view with a typical HTML template peppered with appropriate <%=...> where view data needs to be inserted would seem to be the sensible approach. Even where you might want to loop.
BTW, why isn't code-behind an easy option?
In your controller:
return Content(contentGoesHere, "application/msword");