I have a web app that has a form on just about every page. In order to make sure each form renders the same, as to make changes easier, I want to render all of my form controls in c# in a central place so if I need to add a class to the input or change something, I only have to do it once.
At the moment, I am just using a load of static classes like TextInputHelper, CheckboxInputHelper etc that use StringBuilder to build up the HTML and returns a string to my view.
For example, all of my forms controls are of the basic form:
<section>
<label class="label">Label Text</label>
<label class="input">
...Input Element...
</label>
</section>
What I would like to do is improve this situation as I still have a lot of duplication between the different helper classes, particularly for the wrappers to the form elements. My initial thoughts are to have a class called something like BaseFormControl that has a virtual Render method that has the outer wrapper for the control, then create other classes that implement this to do specific things like a TextFormControl that puts
<input type="text".....
inside the wrapper.
Am I on the right path for this, and/or is there a design pattern that is appropriate for what I want to do?
From my POV what I read is that you over complicating your server side just because of a CSS/HTML standardization that be easily solved from the client side.
If you still want to go for the server side approach the pattern that seems to apply to your approach is the Adapter(Wrapper) pattern meaning that you probably would want to create control wrapper clases to meet your needs for each control that renders a different html from what is offered by ASP.NET built-in controls.
If what you want to do instead is to format a group of controls then a UserControl is way much better approach.
Remember that ASP.NET was build with the spirit of trying to keep layers separated the View from the Code therefore any attempt to generate html from the server side has to be an exception and not a rule.
Related
I have a requirement for multiple tasks to be populated dynamically in response to a user 'add task' button. I don't know how many tasks will be created by the user and would prefer not to set a maximum number with hidden fields as this would be inefficient with regards to database storage space.
Tasks can be thought of as child elements to notes and are stored in separate tables. I've managed to display multiple tasks on the view but I'm less confident with front-end development and am unsure of how I can add an input field without calling a post-back, thus entering 'mid-stream save' territory..
<html>
<div class="container">
<!-- #using(Html.BeginForm()) { -->
<div>
<label asp-for="Note">Note</label>
<input id="Note" />
<span asp-validation-for="Note"></span>
<label asp-for="Task">Task</label>
<input id="Task" />
<span asp-validation-for="Task"></span>
</div>
<div>
<button type="button">Add Task</button>
<input type="submit" value="Save" />
</div>
<!-- } -->
</div>
</html>
I have also made a small jQuery function that can create task inputs upon the 'add task' button, but with little success in connecting it to the controller/model.
I've had AJAX with JSON recommended to address this requirement but I'm unsure of how this can be implemented in a form and how this can then be read by the controller and ultimately the model?
I'm open to design alternatives, should it better suit my solution.
Ok, I'll try to explain here the approach I usually use to this type of problems, after quite a while developing different applications it finished as one of my favorites.
First of all, If I'm understanding you well, you have a view where a form is build, as a part of a client interaction you need to inject elements that depends on the main entity of your form (usually as a one to many relationship). I will call those "subforms" during this answer.
You need to:
A) Manage client interaction with the elements added/modified/replaced
B) Send the final data to your server's controller so data can be persisted into database.
My approach to this type of situations is try to manage all the client interactions in the client, sending final data only on the end, after user pushes "Save" button.
Obviously... this is not valid for EVERY situation, as sometimes specific requirements could make this solution not recommended.
For the client part:
I build the core of the form on a normal way, through a standard view, usually I place specific containers to inject there the information of the "dynamic" data.
On the "Add task" button I add a listener that creates the HTML for one element of the subform and appends it to the container. Usually this code includes a delete button to eliminate it from the DOM as a whole. I also have a listener to manage those interactions.
Ok... so you now have a form where some buttons can add and remove small parts of code that represents individual elements of your subform.
Include in your client code a data structure (I usually use a JSON object) that represents a list of elements of the subform.
When your user hits the "Save" button, capture the event and, before sending data back to server make this two things:
Loop through your subform structure reading the info that it contains at this moment and store it in your client data structure (the JSON object I refer before). Now you have a JSON object with all your subform information.
Stringify it and store it in a hidden text component which is sent within the form. All of your "subform" fields could be outside of the form, as they doesn't need to be sent, the info travels back to the server in a "class instance" as a JSON structure.
In the server:
When your controller receives your form data, there will be a field which stores a string representing the whole info your user sent through the "subform".
Now you just need to get this info and manage it in the way you like. You can, for example, design a class to load this type of info and send it to the database through your usual persistence engine.
Keep in mind that in this package you are storing not only the elements added, you also have the elements that have been changed since the last edit, so you will probably have to look for them in the database and modify them.
This is quite a wall of text, and probably it's less clear to understand the idea than it's on my mind, so feel free to ask if you don't understand something or there is anything that is not clear enough.
Simple question;
When are Custom HTML Helpers supposed to be used. Are we supposed (as intended by the developers of MVC) to implement an Extention method for all tags/logic that are reused across the views?
I'm curious about this, as we currently have a medium sized project that needs to be refactored. Alot of different interns have been working on this, and its time to do a cleanup.
Use Html Helper for rendering an Html Element. That element may contain inner elements, but your helper should mean the outermost element. Let me give you an example. Say, you want to render an Image button with some specific attributes so that your image button will look like this:
<button title="my button" onclick="onClickFunctionName()">
<img src="...." />
</button>
So, an Html Helper with following signature can be very useful:
#Html.ImageButton(title:"my button", onclickFunctionName:"onClickFunctionName", imageSource:"....")
Same like an image button, you can encapsulate creating a Table using Html Helper.
If you want to encapsulate a piece of html markup for some partial layout, then you should use Partial Views. For example, a Partial View can be used for rendering Login box with User name and Password and a Remember Me Checkbox. In this case, an HTML Helper wont be a good idea to use.
In situations where you want your links to work with your routing configurations. You use HTML property. It's instance of IHtmlHelper which contains methods for generating snippets of html. You could type them by hand, but this html property has a logic behind the scenes to use some metadata or configurations in your application. Also, HTML Helpers know built-in conventions in the MVC framework.
I am designing a webapp using ASP.NET and jQuery and I could use some advice.
Currently, the ASP.NET page renders an unknown number of elements that perform an action when clicked. Javascript on the front-end handles the click event based on which specific element was selected.
Each element is embedded with information that the javascript function requires. This informaion is added as extra attributes. So for example, a given element might look like
Link 123
jQuery then attaches a click event and uses the extrainformation attribute as a parameter for an internal function. Each element has 3-5 parameters.
This works great, but I have heard recently that it might not be best practice since it is not WC3 compliant. One possible solution would be for each element to directly call the internal javascript function with the necessary parameters. However this makes me uncomfortable because I lose the separation of concerns between rendering the page and executing the client-side logic.
Is there a better way to do this? Or maybe I'm just overthinking it?
Yes there is a better way, its called HTML5 Data Attributes you can access them from jQuery using the $.data() interface.
For Example:
//instead of
Link 123
//use
Link 123
//then access it like
var info = $('#123').data('info');
alert(info); //alerts: 'something important'
Basically anything starting with data- is stored as data about that element in the DOM, jQuery can access this data via the $.data() function.
I have a user control which when added to the markup via the Toolbox or manually typing
<myNameSpc:myCtrl ... I would like to spit out:
<myNameSpc:myCtrl>
<template></template>
</myNameSpc:myCtrl>
I remember doing this for windows workflows and it involved implementing something like a TypeConverter and WorkflowXmlSerializer so it maybe possible for user controls as well I'd guess ? the only thing is that I don't have time to research this matter now, so I was wondering if anyone would be kind enough to point me in the right direction so that I don't have to dig deep into the designer serialization of VS (which I remember was a big pain).
For your custom control, you can specify a ToolboxDataAttribute which defines the default html that will be generated when you drag a control onto the design service. E.g.:
[ToolboxData("<{0}:myCtrl runat="server"><template></template></{0}:myCtrl>")]
public class myCtrl : System.Web.UI.Control
{
}
For the manual generation you can create a Code Snippet. The best way to do that is find existing ASPX snippet and modify it to gen your control. I'm assuming you are using VS 2010.
I want to show a pop-up on click of a button. The pop-up should have a file upload control.
I need to implement upload functionality.
The base page has nested forms. Totally three forms nested inside. If I comment the two forms then I can able to get the posted file from Request Object. But I was not suppose to comment the other two forms. With nested forms I am not getting the posted file from the Request object.
I need some protocols to implement this.
I am using C#. The pop-up was designed using jQuery.
As suggested, I am posting the sample code here.
<form id="frmMaster" name="frmMaster" method="post" action="Main.aspx" Runat="server" enctype="multipart/form-data">
<form method='Post' name='frmSub'>
<input type="hidden" name='hdnData' value=''>
</form> // This form is driven dynamically from XSL
<form method='Post' name='frmMainSub'>
<input type="hidden" name='hdnSet' value=''>
</form>
</form>
Note:
Commenting the inner forms works fine. But as it required for other functionalities not suppose to touch those forms.
I have given this code for sample purpose. The actual LOC in this page is 1200. and the second form is loaded with lots of controls dynamically. I have been asked not to touch the existing forms. Is it possible to do this functionality with nested forms?
You can have multiple HTML form tags in a page, but they cannot be nested within one another. You will need to remove the nesting for this to work. If you post some of your code, you're likely to get more help with some specific recommendations to address this.
From your posted code, it's also unclear why you'd even be tempted to use multiple forms. Can you elaborate on why you think you need multiple forms here? You don't have explicit actions in your subforms, so it's hard to tell where you want them to post, but I'm guessing it's all posting to the same page. So, why multiple forms at all?
You could always try putting one of the inner forms onto another page and serving it up in an iframe. That way the inner form is not technically inside the outer form. This will require you to alter some of the html, but there's really no way around that.
In your situation you're looking at a hack no matter how you put it. You aren't supposed to have nested forms.
Since you're using Javascript to do this, you could try moving the form element that is posting back out of the parent forms and then performing the .submit() action after it's been moved.
It's a ugly hack - but I so is the HTML -- :) (I kid, I kid!)