ASP.NET MVC 2 - Repopulating file inputs in an edit view - asp.net-mvc-2

Is there a way to repopulate a form's file inputs in an Edit action's view? I'm using the same editor template for both my Create and Edit actions, and would like it so that when the form comes up during editing, the file input fields are automatically repopulated from the view model.
If so, the file names would come from the back end (since the files associated with the model are already in the system). With that being the case, would they still be considered HttpPostedFileBase objects, even though they didn't originate from the user's machine?

when you have your edit action you should pass model to view again:
//Get
public ActionResult Edit(int id){
YourModelOrEntity model = load content here
return View(model);
}
//[get]
public ActionResutl Edit(MyModel model){
if(! ModelState.IsValid) return View(model); //<- this is how you pass it back to the user
}

Related

Thymeleaf form with multiple objects of the same class

Simple problem but can't find a solution: I have a Thymeleaf form used to add a new object, say of a Book class. It works perfectly well and I only need that particular form for adding new objects, not editing the existing ones. The question is: how can I put several objects of the Book class in the same single form? So, purely for convenience, instead of filling form for a single book and clicking Send you can fill form for several books at once and only then click Send, have them all inserted into the database (in whatever order) and also have the option to fill the form partially (e.g. the form has room for 5 books but it will also accept 1, 2, 3 or 4 and you can leave the rest blank).
Edit: I've tried passing a list of object to the Thymeleaf template with the form bound to the whole list and iteration inside, but Thymeleaf throws BingingResultError upon rendering it.
You need to use a wrapper object to realize what you want.
Something like:
public class BooksCreationDto {
private List<Book> books;
// default and parameterized constructor
public void addBook(Book book) {
this.books.add(book);
}
// getter and setter
}
Then you need to pass this object as a model attribute in your controller:
BooksCreationDto booksForm = new BooksCreationDto();
model.addAttribute("form", booksForm);
bind fields using index property
th:field="*{books[__${itemStat.index}__].title}"
and get back the result with
#ModelAttribute BooksCreationDto form
in your controller.
For a complete and detailled explaination visit: https://www.baeldung.com/thymeleaf-list

Zend Framework - Change order of action output

I have two actions for image albums in my controller, the first creates a form to create a new album and handles the POST and the second generates a list of the existing albums. The form posts to the first action and then puts the list action on the actionstack. This order is necessary as otherwise a newly created album wouldn't appear in the list.
So in my HTML output there is first the output of the createAction-view and then of the listAction-view. But for styling reasons I want to change the order of view output of the two actions in my HTML. Is there a way I can have the list followed by the form without changing the order in which the actions are executed?
You should try and avoid using the action stack if at all possible. You can avoid this requirement completely by simply redirecting to the list view after handling the POST data. This also prevents users accidentally submitting the same album again by refreshing the page. If you still want the form to be displayed under the list, just add the form to that action as well so you can output it in the view under your albumn list.
public function createAction()
{
$form = new Yourapp_Form_Album();
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()) {
// save the data and redirect
}
}
$this->view->form = $form;
}
public function listAction()
{
// load albums and assign to the view
// if you want the form under the list
$this->view->form = new Yourapp_Form_Album();
}

How to validate and post data from dynamic form in ASP.NET MVC 2

I have an existing ASP.NET MVC 2 application that I've been asked to extend. I am adding a new feature to the site where I generate an employee assessment form based on a dynamic list of questions retrieved from our HR system. I have everything working with the exception of validation and posting the responses back to the site. Here's some details:
I retrieve a list of "Questions" from our back-end system via a web service call.
Each "Question" contains the text to display as well as the following settings:
The question Type (corresponds to textbox, textarea, radio button list or checkbox list)
If comments are allowed
If an answer is required
When applicable, the list of possible responses
To generate the form, I use a for-each loop over the list of Questions. I use the value of the QuestionType property to determine which partial view to render (one for each of the types). For example, if QuestionType == SingleChoice, that partial renders the choices as a radio button list. If comments are allowed for the question, I also render an additional textarea field to hold the user's comments.
As I said, rendering the form is working fine but now I need to:
A. Enforce when an answer is required. I'm using DataAnnotations for validation everywhere else in the solution but since I'm not working against a static model, I don't see how I can do that.
B. Post the results back to the site. For each question, there can be text entered into a textbox or textarea, a selected value for a radio button list or multiple selected values for a checkbox list. Plus, each question could also have additional text sent back in the form of a comment.
All of the examples that I've seen working with dynamic "lists" are only concerned with posting a single value for each field and it is always the same type (e.g. a list of textboxes). With the variations I have to support, plus the need to send back the entered/selected value(s) and a comment for each question, I'm stumped.
Any guidance is appreciated.
I've just finished completing exactly the same task.
I chose to write a custom model binder for my dynamic form object. The model binder pulled out a bunch of prefixed form keys for hidden fields which contained some delimited meta data about the question (i.e IsRequired, QuestionType, QuestionId etc etc)
I'm using MVC3 but I think this should all work in MVC2.
I created a ModelBinder like:
public class DynamicFormModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// Create the object to be bound to (I had a kind of form object
// with a simple list of answer objects
DynamicForm form = new DynamicForm(new List<Answer>());
HttpRequestBase request = controllerContext.HttpContext.Request;
var keys = request.Form.AllKeys.Where(k => k.StartsWith("MyFormsKeyPrefix_Meta_"));
foreach (var key in keys)
{
// Loop over each question's meta data. Metadata will always be present
// even if the user hasn't selected an answer as it's a hidden field
// TODO: Split the meta data and pull out IsRequired, QuestionType etc
// TODO: Get all the posted form values for the question (these values
// will come from textboxes, dropdowns, checkboxes etc)
// Use a prefix like: MyFormsKeyPrefix_Answer_{QuestionId}
// textboxes & dropdowns will only ever have one value
// but checkboxes could have multiple
// TODO: If it's a mandatory question then ensure there is at least
// one posted value that is not an empty string
// If there is a validation error then add it to the model state
bindingContext.ModelState.AddModelError(key, "Field is required");
foreach(var answerHtmlName in answerHtmlNames)
{
// TODO: Loop over each posted answer and create some kind of nice
// Answer object which holds the QuestionId, AnswerId, AnswerOptionId
// and Value etc.
// Add the answer to the forms answers list
form.Answers.Add(answer);
}
}
return form;
}
}
I register the ModelBinder in Global.asax using the following:
ModelBinders.Binders.Add(typeof(DynamicForm), new DynamicFormModelBinder());
So, the action method that recieves the form post looks something like:
public ActionResult ProcessForm(DynamicForm form) {
if(ModelState.IsValid)
{
DynamicFormService.Process(form);
return RedirectToAction("TheHttpGetAction");
}
return TheHttpGetAction();
}

Make form submit with addition parameters. ASP.NET MVC

I would like to submit form by click on the button 'Submit'. All ok, but I have addition checkboxes without binding to model. This checkboxes were added dynamically. How to send form to client with these checkboxes and grab data on server.
[HttpPost]
public ActionResult Add(PremiumSlots PremiumSlots, FormCollection collection)
{
string chkbx = collection["yes-no"];
// "yes-no" name of checkbox (Should be same for all checkboxes)
// you will get comma separated values, perform split operation on string and use individualy
}

Pasing data from one form to other

I have a form with a grid and I want to pass info from the first form to second based on which row is selected when the user clicks the edit button.
what is the best way? and how should I decide how the form should be blank if the the user wants to add a new or fill the second(edit) form with the values from the selected row of the first forms datagrid?
The row values are all properties of the same object.
I can delete and add a new object, its editing an exsisting one that I am having a hard time with, and how should I load the second form?
I am currently creating and instance then instance.Show();
This is working the open a blank form, but I want to loadd it with the object based on the selected row when the user wants to edit an exsisting record.
Let's say your form1 is the form with data grid (grdMyData) that's displaying rows of MyClass class instances, and form2 is the form for editing the data of the given row.
When user clicks Edit, you could use this:
private void btnEdit_Click(sender e, EventArgs arg)
{
if (grdMyData.SelectedRows.Count == 0)
return; //nothing to do
MyClass selectedRow = (MyClass)grdMyData.SelectedRows[0].DataBoundItem;
Form2 frm2 = new Form2(selectedRow);
if (frm2.ShowDialog() == DialogResult.OK)
{
//do something if needed
}
}
This code is assuming you have the proper Form2 constructor which takes the type of object it works with. With this when you are working in Form2 the data will automatically affect the Form1 display because they're working with the instance of the same object.
I would suggest exposing an event in one form that the other form can consume.
Here is the offical tutorial
http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx
Basically it would be something like this
// Source form
public event YourEventHandlerType EventName;
// Wherever the event occurs
EventName.Invoke(...);
// Destination form
this.referenceToSourceForm.EventName += MyEventHandler(...);
So, you will need some reference to the source form in the destination form, or you will need to setup the event handling outside of the two forms otherwise.