Text change event for textbox not updating assigned value - c#

I am building a shopping portal where I need to accept quantity of products and pass it to an action named order
As you can see in picture above, I added a textbox for accepting quantity for each of the product, then I built an actionlink using following code
#Html.ActionLink("Order Now", "OrderNow", "ShoppingCart", new { id = item.prod_id, qty = #quantity }, new { style = "color: white;" })
to get quantity I added new int quantity attribute to view, as
int quantity = 1;
but how to update this quantity variable when users change the text in qty textbox.
Below is my View code:
#Html.TextBox("qty","", new { id=#item.prod_name, placeholder="Qty", style="width:20px; height:15px; font-size:small;" })
<script type="text/javascript">
$('##item.prod_name').change(function () {
}
});
</script>
#Html.ActionLink("Order Now", "OrderNow", "ShoppingCart", new { id = item.prod_id, qty = #quantity }, new { style = "color: white;" })
Here is my controller action method
public ActionResult OrderNow(int id, int qty)
{
if (Session["cart"] == null)
{
List<Item> cart = new List<Item>();
cart.Add(new Item(p.FirstOrDefault(), qty));
Session["cart"] = cart;
return RedirectToAction("ViewCart", new { ids = p.FirstOrDefault().prod_sub_cat_id });
}
else
{
List<Item> cart = (List<Item>)Session["cart"];
cart[index].quantity = qty;
Session["cart"] = cart;
return RedirectToAction("ViewCart", new { ids = p.FirstOrDefault().prod_sub_cat_id });
}
}

You don't really want a link to a GET method here. Your modifying data (and would not want this to be added to the browser history) so you should be posting the data. For each product, add a form element with a textbox for the quantity and a submit button for the 'Order Now` action (style it to look like a link if you want)
#using (Html.BeginForm("OrderNow", "ShoppingCart", new { id = item.prod_id })
{
<input type="text" class="???" name="qty" placeholder="Qty" />
<input type="submit" value="Order Now" class="???" />
}
Side notes:
Add class names and use css rather than including inline styles such
as style="width:20px; height:15px; font-size:small;"
You could also use #Html.TextBox("qty", new { id = "",
#class="???", placeholder = "Qty"), but note the id = "" which
removes the id attribute to prevent invalid html due to duplicates

Related

Select Item of dynamic list in HTML

I'm doing a management application users have a part where I have a form with a <select></select>
Which is filled from a
#{ Html.RenderAction ("ListaTipoDeUsuarios", new {selected = 0}); }
This (Index.cshtml):
...
<div class="lg-xs-12">
<label>Tipo Usuario</label>
<select name="tipoUsuario" class="form-control" >
#{Html.RenderAction("ListaTipoDeUsuarios", new { selected = 0 });}
</select>
</div>
....
I have my function in the controller which performs the query to bring the list of types of users (HomeController.cs)
[ChildActionOnly]
public PartialViewResult ListaTipoDeUsuarios()
{
string dtTipoUser = client.GetTiposUsuario("{}");
DataTable dt = (DataTable)JsonConvert.DeserializeObject(dtTipoUser, typeof(DataTable));
List<TipoUsuarioBO> listaTiposUsuarios = new List<TipoUsuarioBO>();
foreach (DataRow row in dt.Rows)
{
TipoUsuarioBO tipoUsuario = new TipoUsuarioBO();
tipoUsuario = TiposUsuarioBR.MapeoTipoUsuario(row, tipoUsuario);
listaTiposUsuarios.Add(tipoUsuario);
}
return PartialView(listaTiposUsuarios);
}
And my view with the list (ListaTipoDeUsuarios.cshtml)
#foreach (var item in Model)
{
<option value="#item.Id">#item.Id - #item.Descripcion</option>
}
My question is, how to make when loading the list brings one of the selected item.Currently when charging the view brings selected by default the first item in the list.
NOTE: Try changing the "0" of the "new selected = {0}" but does nothing.
You will need to change the Model of the PartialView which is rendering the options. You have 2 options.
Change the existing TipoUsuarioBO object to add another property named SelectedID,
OR
Create a new Model with the following declaration.
public class OptionsModel <-- Rename to naming conventions
{
public List<TipoUsuarioBO> TipoUsuarioBO { get; set; }
public int SelectedID {get; set; }
}
And, while rendering option elements, use the following
#foreach (var item in Model.TipoUsuarioBO)
{
<option value="#item.Id" #Html.Raw(#item.Id == Model.SelectedID ? "selected" : "") >#item.Id - #item.Descripcion</option>
}
Why you don't try using List<SelectListItem> as the model of ListaTipoDeUsuarios.cshtml view.
[ChildActionOnly]
public PartialViewResult ListaTipoDeUsuarios()
{
string dtTipoUser = client.GetTiposUsuario("{}");
DataTable dt = (DataTable)JsonConvert.DeserializeObject(dtTipoUser, typeof(DataTable));
List<SelectListItem> listaTiposUsuarios = new List<SelectListItem>();
foreach (DataRow row in dt.Rows)
{
TipoUsuarioBO tipoUsuario = new TipoUsuarioBO();
tipoUsuario = TiposUsuarioBR.MapeoTipoUsuario(row, tipoUsuario);
listaTiposUsuarios.Add(new SelectListItem()
{
Text = tipoUsuario.Id+"-"+tipoUsuario.Descripcion,
Value = tipoUsuario.Id.ToString(),
Selected = true //if you want this item selected otherwise false
});
}
return PartialView(listaTiposUsuarios);
}
and your view
#Html.DropDownList("The name of the field", Model, new { #class = "any-class"})

dropdownlistfor within a 'for' loop not posting values

I have multiple dropdownlists which are rendered with a for loop and I'm having a problem getting them to post the selected value to the controller. In my query my selectlist is made like this:
model.CreateGroupForm.Genders = new List<SelectListItem>
{
new SelectListItem() {Text = "Either", Value = "Either"},
new SelectListItem() {Text = "Male", Value = "Male"},
new SelectListItem() {Text = "Female", Value = "Female"},
};
My first problem was even getting my dropdown to display the database value, even though I confirmed it was retrieving the correct value. It wouldn't work with this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender, Model.Createform.Genders)
<button type="submit" class="btn btn-primary" title="Update name and description of this group">Update</button>
}
}
After doing some digging on Stack, I discovered that each dropdown rendered needs it's own separate list. So I changed it to:
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender,
new SelectList( Model.CreateGroupForm.Genders,"Value", "Text",Model.ExistingGroups[c].Gender))
This then correctly displays the queried value, however it just posts null to the controller when I submit the form. I'm having the same issue with a checkboxfor boolean within the for loop.
My ActionResult in the controller just expects a string value and looks like this:
public ActionResult EditGroup(EditGroupInput input)
{
var command = new EditGroupCommand(input.Gender);
....
My view model looks like this:
public IList<CommunityGroup> ExistingGroups { get; set; }
public CreateGroupInput CreateGroupForm { get; set; }
And then the above 2 classes have the properties mentioned in the code.
I've discovered the problem, which is that dropdownlistfor, checkboxlistfor etc do not like operating within a 'for' loop. I certainly don't have the technical know-how to understand why, but when I changed dropdownlistfor to dropdownlist it worked. So the solution looks like this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownList("Gender", new SelectList(Model.CreateGroupForm.Genders, "Value", "Text", Model.ExistingGroups[c].Gender))
...
}
}
EditGroupInput should be a collection of ExistingGroups as controller action method are strongly binded with view.or use formcollection as parameter and see what are all the keys being posted from view to controller.

adding new values to database from view whose model is a list

in an ASP.NET-MVC 5 application I have the following models
class Employee {
int EmployeeID {get;set;}
string FirstName {get;set;}
List<OfficeLocations> OfficeLocations {get;set;}
}
class OfficeLocations {
int OfficeLocationsID {get;set;}
//foreign key
int EmployeeID {get;set;}
string Value1 {get;set;}
string Value2 {get;set;}
}
I have an edit view for modifying or ADDING different office locations that an employee could belong to. It looks something like this:
#model List<Project.Models.OfficeLocations>
#for (int i = 0; i < Model.Count; i++) {
#Html.EditorFor(m => m[i].CitLocation, new { htmlAttributes = new { #class = "my_editor" } })
#Html.HiddenFor(m => m[i].OfficeLocationsID)
#Html.HiddenFor(m => m[i].EmployeeID)
}
//extra editor box for adding a new value
#Html.Editorfor(??????.Value)
I'm a little confused as to how to add new entries to my model (list) in the database table. What do I put in the parameter for the extra Editorfor box (where all the ???? are)
also, what would the controller action method look like?
change your viewmodel to have an officelocation and a list of officelocation... With that you can add the non list officelocation object in you extra editor box... Or you can just retain your viemodel like that and just manually create a model using jquery and pass it using an ajax jquery...
To fix this issue I came up with the following javascript:
<script>
$(document).ready(function () {
index = 0;
});
$('#add_button').click(function () {
var placeHolderNameAttribute = "List2[#].Value1";
var indexedNameAttribute = "List2[" + index + "].Value1";
var placeHolderIdAttribute = "new_lastName_input";
var indexedIdAttribute = "new_lastName_input" + index;
document.getElementById(placeHolderIdAttribute).name = indexedNameAttribute;
document.getElementById(placeHolderIdAttribute).id = indexedIdAttribute;
var clone1 = $("#new_lastName_input" + index).clone();
document.getElementById(indexedIdAttribute).name = placeHolderNameAttribute;
document.getElementById(indexedIdAttribute).id = placeHolderIdAttribute;
if (index == 0) {
$('#nlnPlaceHolder').remove();
}
$('#LN_editor_box').append(clone1);
index += 1;
});
</script>
and the following placeholder input field
<input id="new_lastName_input" class="my_editor" type="text" name="List2[#].Value1" value="New Last Name" />
and now my controller post method accepts two parameters, the original list of updated/edited values, and a new list of only new values.
ActionResult myMethod(List<OfficeLocations> list1, OfficeLocations[] list2)
and if the value is in list1 then it will update in the database, and if it's in list2 it will be added

how to Prevent Serverside data load to dropdown list in Asp.net MVC

I have dropdown list which was created dynamically like:
#for(int i=0;i<=count;i++)
{
#Html.DropDownListFor(m => m.GetTimeSheetDetails[i].PROJ_ID, (SelectList)ViewBag.ProjectList, "-- Choose a Project --", new { #class = "ddlProjectvalue" })
}
<input type="submit" value="Add Record" name="btn"/>
in Contoller I am loading data to dropdownlist:
[HttpPost]
Public ActionResult Timesheet()
{
TimsheetModel model=new TimesheetModel();
if(btn=="Add Record")
{
var data= Session["ddlData"] as IEnumerable<SelectListItem>;
SelectList list1=new SelectList(data,"Value","Text",model.ProjID);
ViewBag.ProjectList=list1;
count++; // ADDS NEW RECORD
return View();
}
else
{
var result = (from proj in db.PROJECTs where proj.IS_DELETED == "N" select new { Value = proj.ID, Text = proj.NAME })
SelectList list = new SelectList(result, "Value", "Text", tm.PROJ_ID);
ViewBag.ProjectList = list;//Data loaded here for Dropdown list
}
return View();
}
Now My Scenario is if count=5 which means if we have five dropdown lists, when I select item in first dropdown list should not show in second dropdown list and if we have select item in second dropownlist should not show items of first and second in third dropdown list. for that I have written script like:
<script>
$(document).ready(function () {
$('.ddlProjectvalue').change(function () {
var id = $('.ddlProjectvalue').attr('id');
var selector = "#" + id;
var selectedValue = $(this).val();
$.ajax({
url: "#Url.Action("GetDDLData","Employer")",
data: { selectedValue: selectedValue, id: id },
dataType: "json",
type: "GET",
error: function () {
alert(" An error occurred.");
},
success: function (data) {
debugger;
$("" + selector + "").removeClass("ddlProjectvalue");
$('.ddlProjectvalue').empty();
var optionhtml1 = '<option value="' +
0 + '">' + "--Choose a Project--" + '</option>';
$(".ddlProjectvalue").append(optionhtml1);
$.each(data, function (i) {
var optionhtml = '<option value="' +
data[i].Value + '">' + data[i].Text + '</option>';
$(".ddlProjectvalue").append(optionhtml);
});
}
});
});
});
</script>
and when i pass selected value to controller like:
public ActionResult GetDDLData(string selectedValue, string id, string addrecord)
{
int projectid = Convert.ToInt32(selectedValue);
if (id == "GetTimeSheetDetails_0__PROJ_ID")
{
IEnumerable<SelectListItem> projectslist = (from proj in db.PROJECTs where proj.IS_DELETED == "N" && proj.ID != projectid select proj).AsEnumerable().Select(projt => new SelectListItem() { Text = projt.NAME, Value = projt.ID.ToString() });
var result = new SelectList(projectslist, "Value", "Text", tm.PROJ_ID).ToList();
Session["ddlData"] = result;
ViewBag.ProjectList = result;
return Json(result, JsonRequestBehavior.AllowGet);
}
else
{
var result = Session["ddlData"] as IEnumerable<SelectListItem>;
var query = (from data in result where data.Value != selectedValue select data) as IEnumerable<SelectListItem>;
Session["ddlData"] = query;
return Json(result, JsonRequestBehavior.AllowGet);
}
}
Now my problem is when I add new record by clciking on Add button, loading Session["ddldata"] data to total dropdown list instead it should remain selectlist item in first dropdownlist for first time, I need like when i first select a dropdownlist item in first dropdown list it should remain same when add record also. it means i should prevent server side load on first select list item and vice versa.
Note: Due to some issues i should add record on server side only
How I can prevent it, I tried like preventDefault or return false using jquery, but not working, Any Ideas? how can I fix it.
I think you are overcomplicating things here. You don't really need to request new options from server. Why not just filter the option out on the javascript side?
$(document).ready(function() {
$('.ddlProjectvalue').change(function() {
updateDDLValues();
});
updateDDLValues();
});
function updateDDLValues() {
// Display all
$('.ddlProjectvalue option').show();
// Hide all selected options from other selectlists
$('.ddlProjectvalue').each(function(i,element) {
var selectedvalue = $(element).find('option:selected').val();
$('.ddlProjectvalue').not(element).find('option[value="'+selectedvalue+'"]').hide();
});
}
Fiddle:
http://jsfiddle.net/Pt7qV/2/
Update:
As for the serverside part of your question, there are some serious flaws in your code. You increase the count property in your controller and use the variable clientside. First you'd think that's how it's done but nope it doesn't work that way.
You are returning View when Add Record is submitted but you aren't returning any model with it.
Your TimsheetModel would look something like this:
public class TimsheetModel
{
public int Count {get; set;}
}
In your controller you pass this to the view:
TimsheetModel model=new TimesheetModel();
if(btn=="Add Record")
{
var data= Session["ddlData"] as IEnumerable<SelectListItem>;
SelectList list1=new SelectList(data,"Value","Text",model.ProjID);
ViewBag.ProjectList=list1;
model.Count++; // ADDS NEW RECORD
return View(model);
}
And in your view:
#model TimsheetModel
#for(int i=0;i<=Model.Count;i++)
{
#Html.DropDownListFor(m => m.GetTimeSheetDetails[i].PROJ_ID, (SelectList)ViewBag.ProjectList, "-- Choose a Project --", new { #class = "ddlProjectvalue" })
}
<input type="submit" value="Add Record" name="btn"/>
I'd suggest you to go back to tutorials or books a bit, this is quite basic stuff after all. I won't go into how you are going to handle database side etc. since I think this answer would just escalate into explaining basic stuff.

Loading selected radio buttons using an editor c#

In relation to this question:
StackOverflow - Grouping radio buttons in c# mvc
I have managed now to load and save the selected options from the form into a database but now the user may need to edit this.
How do I load the view with the selected user's choices? I cannot see where you can set selected Answer. On load I am getting the default values selected
You can set the SelectedAnswer property value for each Course in your GET action and your EditorTemplate will take care of the rest.
public ActionResult Index()
{
var vm= new OrderViewModel();
//the below is hard coded for DEMO. you may get the data from some
//other place and set the course and options
var q1 = new Course { ID = 1, Name= "Starters" };
q1.Options.Add(new Option{ ID = 12, Title = "Prawn Cocktail " });
q1.Options.Add(new Option{ ID = 13, Title = "Soup" });
q1.SelectedAnswer = 13; //to do : get the selected answer value from DB
vm.Courses.Add(q1);
var q2 = new Course { ID = 1, Name= "Mains" };
q2.Options.Add(new Option{ ID = 42, Title = "Beef" });
q2.Options.Add(new Option{ ID = 43, Title = "Lamp" });
q2.SelectedAnswer = 16;// to do :get the selected answer value from DB
vm.Courses.Add(q2);
return View(vm);
}
There is no change to be made to your editor template. It stays same as the previous answer.
#model Course
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.Name</h3>
#foreach (var a in Model.Options)
{
<p>
#Html.RadioButtonFor(b=>b.SelectedAnswer,a.ID) #a.Title
</p>
}
</div>
Use this:
<%= Html.RadioButtonFor(m => m.Something, "something", new { Checked = "checked" })%>

Categories

Resources