My question is about checkbox boolean value.
See the image below (image is of a View where user chooses the "seminar") and my current implementation.
//in the model, "Popunjen" is checkbox value which displays if a cert
//"seminar" is full or not. Value is set mannually on the "admin" page
public bool Popunjen { get; set; }
I need a functionality where, if user clicks "Upiši se" (Enroll in eng.) on "Seminar" where "Popunjen" or "Full" is true (for ex. last seminar in list), some sort of error messagge is displayed.
Is this best done on the View code of this page? And what would be the code behind it?
Without seeing the code of your MVC, I suppose you're building the View from a Controller [HttpGet] and the table rows are populated from DB query. You could check the value of the "Popunjen" and if it's true disable the "Upiši se", something like:
<td>
#if (item.Popunjen == true)
{
// disable "Upiši se"
// don't show it
}
else
{
// enable "Upiši se"
}
</td>
Related
So I have this form with this inside it
<div class="form-group">
#*<div class="form-check form-check-box">
#for (int i = 0; i < Model.Features.Count; i++)
{
<div class="form-check form-check-box">
<input class="form-check-input" type="checkbox" asp-for="#Model.Features[i].Selected" value="#Model.Features[i].Text">
<label class="form-check-label" asp-for="#Model.Features[i].Text">#Model.Features[i].Text</label>
</div>
}
</div>
And when I post the form and inspect the properties of the SelectedListItem it looks like this
Even though the Selected should be True because I checked it. Everything else that's in the form gets posted fine, like the text input binds just fine to the string Text property inside my ProductModel, I believe the issue is with the way I'm using the checkbox element properties.
So I can see the checkboxes, and I can check them, etc, but when I post the form, nothing related to the checkboxes applies to the ProductModel
public class ProductModel
{
public string Title { get; set; }
public IList<SelectListItem> Features { get; set; }
}
This is how I show set the Model for the view
public IActionResult PostAd()
{
var model = new ProductModel
{
Features = new List<SelectListItem>()
{
new SelectListItem { Text = "Camera", Value = "Camera" },
new SelectListItem { Text = "Touch Screen", Value = "Touch Screen" }
}
};
return View(model);
}
How do I properly use checkboxes so that when I post the form, the data comes through to the model?
This is the action that gets fired when posting
[HttpPost]
public IActionResult CreateAd(ProductModel Product)
{
return View("Index");
}
The problem you are having is that when the form is posted, ASP.NET will bind the posted data to your model, but only input values within the form are posted. The reason your SelectListItem has null Text and Value properties is because these values are not being posted in the form. The form would need to contain an input (such as a hidden input) for #Model.Features[i].Text and another for #Model.Features[i].Value for these to be bound back to the SelectListItem during model binding because it is the input's name that binds it to a model property. But keep in mind, receiving these from even hidden inputs would enable a user to change them to any value they want so you would need to validate on the server side that they are 1) valid values and 2) allowed to be selected.
Given that fact, I find it makes more sense to simply reload the list of available options, in your case Features, in your HttpPost action, then update that rebuilt list with the user's submitted selections.
Now the only problem left is you're not even getting Selected set to true. This is again, because it's based on the input's (the checkbox's) value. asp-for="#Model.Features[i].Selected" will give the checkbox the name it needs to bind back to that property, and will bind its value attribute to the value of Selected. However, you then also define your own value attribute as value="#Model.Features[i].Text" which overrides the one that would've been generated by the asp-for helper. So when your form is submitted, the model binder tries to bind "Camera" to the boolean Selected property which can't be done so it just gets it's default false value. Generally, a SelectListItem is used for a dropdown (<select>) input. There's no reason you can't use it for this purpose, but you could also just use your own model type for the checkboxes.
I'm currently working on an asp.net web form that uses Knockout, Bootstrap, and JQuery. I'm having an issue with data persistence through "Wizard steps."
What I would like to do is take in the mailing state of the client and persist it through to other pages, from there use Knockout to make fields visible and also create validation.
I've read that you can use hidden states to accomplish this but I've had issues getting the value to pass to Knockout and ultimately getting the other fields to show.
Here is the c# that does all the steps page to page.
protected void StepChanged(object sender, EventArgs e)
{
if (IsPostBack)
{
if (QuoteWizard.ActiveStepIndex == 0)
txtFirstName.Focus();
if (QuoteWizard.ActiveStepIndex == 1)
{
Session["State"] = ddlState.Value;
rblMailAddr.Focus();
}
if (QuoteWizard.ActiveStepIndex == 3)
{
txtDriverFName1.Value = txtFirstName.Value;
txtDriverMI1.Value = txtMI.Value;
txtDriverLName1.Value = txtLastName.Value;
String DOB;
DOB = Convert.ToDateTime(txtDOB.Value).ToString();
txtDriverDOB1.Value = DOB;
txtDriverFName1.Focus();
}
I find it odd that the txtDriverFName1.Value = txtFirstNAme.Value; passes properly but I can't get the state from a drop down list or the date of birth to pass from one step to the other.
<select id="ddlState" runat="server" class="form-control" data-bind="value: MailState, updateValue: 'afterkeydown'">
Followed by the list of states, then I try to pass it to knockout to make fields visible:
self.MailState = ko.observable("", { persist: "MailState" });
However, once I reach the next step the values in the ViewState are dropped and
<div class="btn-group" data-toggle="buttons" style="padding-left: 10px" data-bind="visible: MailState() == 'CA'">
no longer becomes visible even when CA is selected in the previous viewstate.
So how would I persist the value of my drop down list through 2 or more steps in the QuoteWizard.ActiveStepIndex and have that assigned to "MailState()" subsequently activating Knockout?
in data-bind the bindinghandler handle to excute expression, then visible bindinghandler will unwrap it to value from observable. But in your code you use
data-bind="visible: MailState == 'CA'" //MailState is observalbe then like function() == 'CA' - that not right
should change to:
data-bind="visible: MailState() == 'CA'"
I need to create a webform where users can add, update, delete, retrieve customer data from a table in an SQL database.
Should have textboxes for each field in the table so that the users can enter details of the fields to update the table in the DB.
What im having trouble with is in the code behind the form i need to make a clear method to clear all the textboxes and the message label.
I also need to set validation requirements for each textbox. But i am unsure how to do this properly.
The textboxes are;
CustID, Firstname, Surname, Gender, Age, Address1, Address2, City, Phone, Mobile, Email, Confirm Email.
Now my main question is, how do i validate the textboxes? For example;
CustID is required. & Must be unique. Must be an integer and must be between 1 & 1000.
You should use RequiredValidator for example
http://www.w3schools.com/aspnet/control_reqfieldvalidator.asp
This will perform validation before submitting data to server ;)
There are also other type of validator, like RangeValidator (for the need to check if the integer is between 1 and 1000).
Example:
<asp:RangeValidator ControlToValidate="youtField" MinimumValue="1" MaximumValue="1000" Type="Integer" Text="The field must be between 1 and 1000" runat="server" />
You can also add a ValidationGroup="save" for example to all your validators and to the button that user should click to save and update data.
Asp.net Have some (5 main types) server validation control's , You can use the validations for your requirement
See this image for understanding validation controls (The image referred from )
More understanding by this MSDN sit3
and here is link for all validation control sample's : click me
Here could be an example for ASP/ MVC - because you have forgotten to specify which technology from ASP. Forms or MVC ?!?
This bellow aplies to mvc and the other attributes are allready defined by the users before me.
Note that the RemoteAttribute can verify a function (validation function) .
namespace ModelValidation.Models {
public class Appointment {
[Required]
[StringLength(10, MinimumLength = 3)]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[Remote("ValidateDate", "Home")]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
To apply validation on a model property that describes a TextBox, then a good proactice is to use TextBoxFor<>(). Like that:
#Html.TextBoxFor((model) => model.ClientName )
You can clear all your controls values by either redirecting to user to another page telling him that form is submitted, New Registration button to redirect user again to Registration page, However if you don't want that you can pick up each control and reset them either in Cs.file or using javascript,
foreach (Control ctrl in form1.Controls)
{
if (ctrl is TextBox)
{
TextBox tb = (TextBox)ctrl;
tb.Text = string.Empty;
}
else if (ctrl is DropDownList)
{
DropDownList dl = (DropDownList)ctrl;
dl.SelectedIndex = 0;
}
else if (ctrl is CheckBox)
{
CheckBox cb = (CheckBox)ctrl;
cb.Checked = false;
}
}
For your validation purpose i strongly suggest you to read about validation in Asp.net , here is a good tutorial you can learn from here
To clear all textbox you can try something like this
foreach (var item in Page.Controls)
{
if (item is TextBox)
{
((TextBox)item).Text = "";
}
if (item is DropDownList)
{
((DropDownList)item).SelectedIndex= 0;
}
//and the other types
}
For the part of validation you have to set the validation fields that you desire and bind it to the field directly on the .aspx page
<asp:textbox ID="Name" runat="server" TabIndex="1"/>
<asp:RequiredFieldValidator ID="rfvName" ControlToValidate="Name" runat="server" ErrorMessage="Name is required">
<asp:ValidationSummary ID="ValidationSummary1" runat="server" DisplayMode ="BulletList" ShowSummary ="true" HeaderText="Errors:" />
When you try to save and one of the condition of your validators returns false, the validation summary will show all the errors written in the errormessage attribute.
I have a WebGrid bound to a Plain Class Object. Nothing Fancy. The Grid features some paging and is used to display a list of users. The Last column of the Grid is an Ajax Action Link which fires a Pop Up DIV with some Edit Controls. On completion of this Edit the OnSuccess Event fires and closes the DIV. This is where I would like to now refresh the grid without losing the current page/search/filter applied. One way that comes to mind is to somehow grab the WebGrids Url and then refreshing it with JQuery, however.. I cant find a way to retrieve the current url and parameters? Anyone tried this before?
UPDATE: Thanks to the answers this is what I have resorted to now:)
The ActionResult called by the ajax edit
[HttpPost]
public ActionResult EditUserDetails(User model)
{
if (ModelState.IsValid)
{
// for the sake of brevity.
// do your edit logic here and then on success you return:
return Json(new { state = "success", id = "1", name = "John", surname = "Doe", etc = "blah" });
}
else
{
return Json(new { state = "failed", message="some error text here maybe?" });
}
}
Then on the edit click I set the class of the row to be .editRowSelected. (i will be changing this to an id rather)
Then onSuccess of the Ajax Update Call:
function onSuccess(ajaxContext) {
var result = eval(ajaxContext);
if (result.state == "Success") {
var row = $('.busyEditRow');
row.html(content);
$('.busyEditRow').removeClass('busyEditRow');
}
else {
// Display some error stuffs here with the message - result.message
}
}
This updates the grid row with the new data:)
Having just edited one record, rather than refreshing the entire grid and having to then post back the filters applied, current page, etc, I would have a function in my controller that returns a partial view containing data for a single user.
You could call this via AJAX after the DIV closes, and use jQuery to replace the row in the grid with the HTML returned from the function.
As long as each row in the grid is identifiable by id, it should be simple enough to find the relevant row and replace it.
Scenario
I have a parent/child model (to be exact a small questionnaire form and a one or more number of contacts). For historic reasons, all of this would have been done on the same form so user would have a form for the parent and one child and they would hit a button to add more children. Child has a few standard fields and the same with the parent, nothing fancy. Main requirement is that the data must not touch the database until all is valid and setup while I would have to go back to server for adding deleting children.
Implementation
It was very quick to get this working in ASP.NET MVC (using MVC 2 with VS 2010). I got two models, one for parent and one for the child and got only one controller. Controller has a Create Method which is a get and gets a default view with a fresh brand new parent containing one child. I use editor template for the child model which works nicely.
I have one HTML form which has a "save" and "add child" and I have "delete" button for each form. Since this cannot be stored in database, I store the temp model in the form itself and it goes back and forth between browser and server. Perfromance is not much of an issue here but the cost of development since there are quite a few of these forms - so please do not get distracted too much by suggesting an alternative approach although I appreciate comments anyway.
In order to find out which child to delete, I create temp GUID Ids and associate them with the child. This will go onto the HTML input's value for delete button (usual trick when you have multiple actions and the same form).
I have disabled caching.
Issue
Please have a look at the snippets below. I have debugged the code and I have seen always correct GUID being passed, correct item removed from the list in the controller and correct items being rendered in the template. BUT ALWAYS THE LAST ONE GETS DELETED!! I usually click the first delete and can see that the last gets deleted. I carry on and first item is the last being deleted.
Controller
public ActionResult Create()
{
EntryForm1 entryForm1 = new EntryForm1();
entryForm1.Children.Add(new Child("FILL ME", "FILL ME"){ TempId = Guid.NewGuid()});
return View("EntryForm1View", entryForm1);
}
[HttpPost]
public ActionResult Create(EntryForm1 form1, FormCollection collection, string add)
{
if (add == "add")
form1.Children.Add(new Child("FILL ME", "FILL ME") {TempId = Guid.NewGuid()});
var deletes = collection.AllKeys.Where(s => s.StartsWith("delete_"));
collection.Clear();
if (deletes.Count() > 0)
{
string delete = deletes.FirstOrDefault();
delete = delete.Replace("delete_", "");
Guid g = Guid.Parse(delete);
var Children = form1.Children.Where(x => x.TempId == g).ToArray();
foreach (Child child in Children)
{
form1.Children.Remove(child);
}
// HERE CORRECT ITEM IS DELETED, BELIEVE ME!!
}
if (ModelState.IsValid)
{
return Redirect("/");
}
return View("EntryForm1View", form1);
}
View snippet
<% for (int i = 0; i < Model.Children.Count;i++ )
{%>
<h4> <%: Html.EditorFor(m=>m.Children[i])%></h4>
<%
}%>
<p>
<input type="submit" value="Create" name="add" />
<input type="submit" value="add" name="add" />
</p>
Child Editor template snippet
<%: Html.HiddenFor(x=>x.TempId) %>
</span>
<input type="submit" name='delete_<%: Html.DisplayTextFor(m => m.TempId) %>' value="Delete" />
Many thanks for your time and attention
UPDATE
I was asked for model classes and I am sharing them as exactly as they are.
Entryform1 is the parent and Somesing is the child.
public class Somesing
{
public Somesing()
{
}
public Somesing(string o, string a) : this()
{
OneSing = o;
AnozerSing = a;
}
[StringLength(2)]
public string OneSing { get; set; }
[StringLength(2)]
public string AnozerSing { get; set; }
public Guid TempId { get; set; }
}
public class EntryForm1
{
public EntryForm1()
{
Sings = new List<Somesing>();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public List<Somesing> Sings { get; set; }
}
I believe that problem lies with ModelState. When the view gets rendered, which I assume is where the issue lies, after the POST, the last value is not displayed i.e. removed from the view.
The issue is that Model.Children.Count will return the correct number of elements to display.
Lets break this down...
So if you have initially had 5 then removed the first one which is at index 0 based on the Guid, you now have items 4 items left with indexes 1 to 4.
However, when rendering the view after the post, the HtmlHelpers do not look at the values in model posted, but rather the values contained within the ModelState. So in the ModelState, item with index 0 still exists and since the loop is now looping to 4, the last element will not be displayed.
The solution, use ModelState.Clear()
OK, as Ahmad pointed out, ModelState is the key to the issue. It contains the collection as such:
FirstName
LastName
...
Sings[0].OneSing
Sings[0].AnozerSing
Sings[1].OneSing
Sings[1].AnozerSing
Sings[2].OneSing
Sings[2].AnozerSing
Now if I delete item 0 from the list, now the items will move up in the list and the data in the ModelState will go out of sync with the model. I had expected ASP.NET MVC to be clever enough to find out and re-order, but well that is asking for too much.
I actually implemented PRG (post-redirect-get) and by keeping the model in session, I was able to display correct information but again, this will remove all the validation in the collection and if model itself is valid, it will happily save and redirect back to home "/". Clearly this is not acceptable.
So one solution is to remove all items in the ModelState and then add a new entry for the model itself (with key of EmptyString). This can actually work alright if you populate it with error "Item deleted" as this will be displayed in the validation summary.
Another solution is to manually change the items in the model state and re-arrange them based on the new indexes. This is not easy but possible.
ModelState.Clear() will Solved this problem.
ModelState.Clear() is used to clear errors but it is also used to force the MVC engine to rebuild the model to be passed to your View.