4

I can't figure out how to do this very simple thing: My page contains a set of textboxes that a user can fill out to add an item to a list. Then the item shows up in a dropdown list.

At that point, I want the "add" textboxes to be cleared. This is the behavior expected by most users, I think. The item has been added; now the textboxes should be empty, ready for the next item to be entered.

However, I can't seem to clear them when I am using Html helpers, e.g., Html.Textbox(...). I like these controls because of the way they "remember" the input in case of input error. However, unlike webforms controls, you can't set them programmatically. They continue to retain the values until the user enters something else.

Is there any way around this behavior? I thought of clearing them in javascript, but I don't want to do that if there are any errors.

UPDATE some of the code; One of my textboxes in the view:

<h6 style="margin-top: 0px">Add custom email template:</h6>
<div style="margin-top: 10px">
<div class="label">Name:</div>
<%= Html.TextBox("addName", "", new { @class="formtext", style="width: 400px" })  %>
<div class="alerttext"><%= Html.ValidationMessage("addName") %></div>
</div>

The class I am using for model binding:

public class ManageEmailTemplatesSubmittedData
{
    [RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage="Names should begin with a character and consist of only characters and numbers")]
    public string addName { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
    public string addDescription { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
    public string addSubject { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
    public string addTemplate { get; set; }

    public string templates { get; set; }

    [RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage = "Names should begin with a character and consist of only characters and numbers")]
    public string editName { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage="Invalid entry; please omit unusual characters")]
    public string editDescription { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
    public string editSubject { get; set; }

    [RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
    public string editTemplate { get; set; }
}

My action:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult CustomEmails(SubmitButtons buttons, ManageEmailTemplatesSubmittedData data)
    {
        bool saved = false;
        string selectedTemplate = data.templates;
        if (ModelState.IsValid)
        {
            ButtonStyles buttonStyles = ButtonStylesCreator.GetSelectListButtonStyles(rc.persistedData.loggedInUser.userType);
            Notification notification = new Notification(rc);
            if (buttons.addTemplate == buttonStyles.addEmailTemplateButtonValue)
            {
                // add an email template
                notification.SaveCustomTemplate(data.addName, data.addName, data.addTemplate, data.addSubject, data.addDescription);
                saved = true;
            }
            else if (buttons.saveTemplate == buttonStyles.saveTemplateValue)
            {
                // update an email template
                notification.SaveCustomTemplate(data.templates, data.editName, data.editTemplate, data.editSubject, data.editDescription);
                selectedTemplate = "";
                saved = true;
            }
        }

        ConfigureEmailsModelBuilder builder = new ConfigureEmailsModelBuilder(rc, rc.persistedData.loggedInUser.userID, selectedTemplate, true, saved);
        return View(builder.Build());
    }

ConfigureEmailsModelBuilder constructs the view model, which includes a SelectList that is the dropdown list of the items that have been added. (The view is strongly typed to the type generated by builder.Build).

Cynthia
  • 2,100
  • 5
  • 34
  • 48
  • What is the Controller action parameter? Is it a typed method? Or using FormVariables? – Shlomo Aug 09 '10 at 23:47
  • I'm using a class whose properties map to the names of the textboxes -- so I guess you could say it's a typed method (is that what you mean?) – Cynthia Aug 09 '10 at 23:51
  • However, I've had the same problem even if I use the FormCollection -- it doesn't seem to make any difference. – Cynthia Aug 09 '10 at 23:52
  • How are you transferring the values from the text box to the dropdown list? Some code samples might be helpful (e.g. the simplified code of your view as well as and action methods that are involved in the user interaction). – marcind Aug 10 '10 at 00:02

2 Answers2

6

The HTMLHelper's first look at the ModelState and ViewData to see if any values match their key and then finally use whatever value you provide them.

If you need to reset the textboxe's value you also need to clear the ModelState entry with the matching key. Another alternative is redirecting to the same page instead of simply rendering a view via javascript or with MVC.

John Farrell
  • 24,673
  • 10
  • 77
  • 110
  • "you also need to clear the ModelState entry with the matching key." -- How exactly do you do that? – Cynthia Aug 10 '10 at 00:26
  • 1
    OK, I think I figured out how to do that: ValueProviderResult abc = new ValueProviderResult("", "", System.Globalization.CultureInfo.CurrentCulture); ModelState.SetModelValue("addName", abc); Is that how you would do it? – Cynthia Aug 10 '10 at 00:29
  • It does seem to blank out the field -- would this be the preferred way? – Cynthia Aug 10 '10 at 00:30
  • @jfar, I think this is the only way besides creating your own html helper that ignores modelstate. – John Farrell Aug 10 '10 at 01:27
  • +1 RedirectToAction should do it, no doubt. I think it's the easiest way – Francisco Aug 10 '10 at 01:40
  • But with RedirectToAction, I can't have my little confirmation message -- "Entry saved" or whatever. I kind of like that; it reassures the user that the expected thing happened. – Cynthia Aug 10 '10 at 15:52
  • ModelState.Clear() works for me in ASP.NET MVC 2. It clears everything, but that's okay for me. – Tim Erickson Dec 14 '10 at 05:13
4

This is working for me on an MVC3 site log on page.

ModelState.Clear();
model.UserName = string.Empty;
model.Password = string.Empty;
ModelState.AddModelError("", "The user name or password provided is incorrect.");

This will clear the login textboxes used for password and username, and keep any model errors.

Greg
  • 747
  • 9
  • 23