Trouble with Parent page subscribing to nested child control eventhandler - eventhandler

I am working on a budgeting project. I have listed incomes in a listview control with deductions nested in another listview control for each income listview item.
I am having trouble subscribing to the DeductionsChanged EventHandler. FOr the example below, I am trying to get the delete action to fire the DeductionsChanged event so that the BindIncome() can be called on the parent page; but DeductionsUpdated is always null, and ucDeductionsEditor_DeductionsUpdated never gets fired.
What am I missing here?
USER CONTROL
namespace BillMoney.UserControls.BillMoneyUserControls
{
public partial class IncomeDeductionsEditor : BillMoney.App_Code.BaseUserControl
{
public EventHandler DeductionsUpdated;
public virtual void OnDeductionsUpdated(EventArgs e)
{
DeductionsUpdated?.Invoke(this, e); // This is always null even though it is subscribed to in lvIncome_ItemDataBound
}
public Int32 Invalue_IncomeId
{
get { return (ViewState["Invalue_IncomeId"] != null) ? (Int32)ViewState["Invalue_IncomeId"] : 0; }
set
{
ViewState["Invalue_IncomeId"] = value;
BindDeductions();
}
}
...
protected void lvDeductions_ItemDeleting(object sender, ListViewDeleteEventArgs e)
{
ListView lvDeductions = (ListView)sender;
Int32 deductionid = DataTypeMapper.GPC_CInt(lvDeductions.DataKeys[e.ItemIndex].Value);
DeductionMGR.Delete(deductionid);
OnDeductionsUpdated(null); // This DOES fire when I click the delete button
BindDeductions();
}
...
private void BindDeductions()
{
List<DeductionDTO> deductions = new List<DeductionDTO>();
deductions = DeductionMGR.GetList(Invalue_IncomeId);
lvDeductions.DataSource = deductions;
lvDeductions.DataBind();
}
}
}
PARENT PAGE MARKUP
<asp:ListView ID="lvIncome" DataKeyNames="IncomeId" runat="server" OnItemDataBound="lvIncome_ItemDataBound">
<LayoutTemplate>
<div id="itemplaceholder" runat="server"></div>
</LayoutTemplate>
<ItemTemplate>
<div class="w3-row content-bubble">
<h3><b>
<asp:HyperLink ID="hlIncomeSource" Text="" NavigateUrl="#" Target="_blank" runat="server"></asp:HyperLink></b></h3>
<div class="row">
<div class="w3-col s3 l3 text-small text-bold">Start Date</div>
<div class="w3-col s3 l3 text-small text-bold">Pay Frequency</div>
<div class="w3-col s3 l3 text-small text-bold">Next Pay Date</div>
<div class="w3-col s3 l3 text-small text-bold w3-right-align">Income</div>
</div>
<div class="row">
<div class="w3-col s3 l3">
<asp:Label ID="lblStartDate" runat="server" CssClass="text-small"></asp:Label></div>
<div class="w3-col s3 l3">
<asp:Label ID="lblPayFrequency" runat="server" CssClass="text-small"></asp:Label></div>
<div class="w3-col s3 l3">
<asp:Label ID="lblNextPayDate" runat="server" CssClass="text-small"></asp:Label></div>
<div class="w3-col s3 l3 w3-right-align">
<asp:Label ID="lblGrossIncome" runat="server" CssClass="text-small"></asp:Label></div>
</div>
<div class="row w3-right-align">
<div class="w3-col l12 border-bottom">
<UC:DeductionsEditor ID="ucDeductionsEditor" OnDeductionsUpdated="ucDeductionsEditor_DeductionsUpdated" runat="server" />
</div>
</div>
<div class="row w3-right-align">
<div class="w3-col l12">
<asp:Label ID="lblTotalIncome" runat="server"></asp:Label>
</div>
</div>
</div>
</ItemTemplate>
</asp:ListView>
PARENT PAGE CODE BEHIND
namespace BillMoney.BillMoneyPages.Income
{
public partial class income_index : BillMoney.App_Code.BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
...
if (!Page.IsPostBack)
{
BindIncome();
}
}
private void BindIncome()
{
// Gross Income
List<IncomeDTO> income_list = new List<IncomeDTO>();
income_list = IncomeMGR.GetList(ActiveUser.UserId);
lvIncome.DataSource = income_list;
lvIncome.DataBind();
}
...
protected void lvIncome_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem item = (ListViewDataItem)e.Item;
IncomeDTO income = (IncomeDTO)item.DataItem;
...
IncomeDeductionsEditor ucDeductionsEditor = (IncomeDeductionsEditor)item.FindControl("ucDeductionsEditor");
ucDeductionsEditor.Invalue_IncomeId = income.IncomeId; // lvDeductions gets bound when Invalue_IncomeId is set
ucDeductionsEditor.DeductionsUpdated += ucDeductionsEditor_DeductionsUpdated;
}
}
private void ucDeductionsEditor_DeductionsUpdated(object sender, EventArgs e)
{
BindIncome(); // This never fires when I click the Delete button on the USERCONTROL
}
}
}

Tuns out I needed to wire it up in the parent listview item created
protected void lvIncome_ItemCreated(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem item = (ListViewDataItem)e.Item;
IncomeDeductionsEditor ucDeductionsEditor = (IncomeDeductionsEditor)item.FindControl("ucDeductionsEditor");
ucDeductionsEditor.DeductionsUpdated += ucDeductionsEditor_DeductionsUpdated;
}
}

Related

How do I add items (including seperators) to a Bootstrap Dropdown-menu in CodeBehind from a database or item list?

After many hours of searching and testing, I arrived at a workable solution.
Thought I'd share it.
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
...
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
PopulateDDLs();
}
}
private void PopulateDDLs()
{
List<string> menu = null;
// Method 1
menu = GenerateListFromTable("MyDatabaseCN", "SELECT MenuList FROM Menu order by MenuList", "MenuList");
AddItemsToDDL(this.YourDDL1, menu);
menu.Clear();
// Method 2
menu.Add("Item 1");
menu.Add("Item 2");
menu.Add("separator");
menu.Add("Item 3");
menu.Add("Item 4");
menu.Add("separator");
menu.Add("Item 5");
AddItemsToDDL(this.YourDDL2, menu, "Select An Item");
}
public List<string> GenerateListFromTable(string db, string sql, string Col)
{
string connectionString = ConfigurationManager.ConnectionStrings[db].ToString();
var retVal = new List<string>();
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(sql, connection))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
retVal.Add((string)reader[Col]);
}
}
}
}
return retVal;
}
public void AddItemsToDDL(HtmlGenericControl d, List<string> menuList, string HeaderTxt = "")
{
if (HeaderTxt != string.Empty)
{
menuList.Insert(0, HeaderTxt);
}
foreach (string menuText in menuList)
{
if (menuText == "separator")
{
var div = new HtmlGenericControl("div");
div.Attributes["role"] = "separator";
div.Attributes["class"] = "dropdown-divider";
d.Controls.Add(div);
}
else
{
HyperLink linkMenu = new HyperLink() { CssClass = "dropdown-item", NavigateUrl = "#", Text = menuText };
d.Controls.Add(linkMenu);
}
}
}
HTML:
<link href="bootstrap.css" rel="stylesheet" />
<div class="input-group">
<div class="input-group-prepend">
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Stuff1</button>
<div class="dropdown-menu" id="YourDDL1" runat="server">
<%--DropDownList loaded from CodeBehind--%>
</div>
</div>
<input type="text" class="form-control" id="Text1" runat="server" readonly>
</div>
<div class="input-group">
<div class="input-group-prepend">
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Stuff2</button>
<div class="dropdown-menu" id="YourDDL2" runat="server">
<%--DropDownList loaded from CodeBehind--%>
</div>
</div>
<input type="text" class="form-control" id="Text2" runat="server" readonly>
</div>
<script src="bootstrap.js"></script>
<script src="jquery-3.5.1.js"></script>
JS:
$(document).on('click', '#YourDDL1 a', function () {
$('#Text1').val($(this).html());
});
$(document).on('click', '#YourDDL2 a', function () {
$('#Text2').val($(this).html());
});
Result:

How do you render a list of components in a loop (Blazor)?

I must be missing something very obvious with blazor... I want to simply render a list containing a component, yet there's no (obvious?) way to reference the iterator (which is a component) for rendering?
TodoList.razor
<input #bind="_newTodo" />
<button #onclick="#AddTodoItem">+</button>
#foreach (TodoItem todoItem in _todoItems)
{
// todoItem is a razor component, yet I can't simply render it here?
// <todoItem />
}
#code {
private IList<TodoItem> _todoItems = new List<TodoItem>();
private string _newTodo;
private void AddTodoItem()
{
if (!string.IsNullOrWhiteSpace(_newTodo))
{
_todoItems.Add(new TodoItem { Title = _newTodo });
_newTodo = string.Empty;
}
}
}
TodoItem.razor
<span>#Title</span>
#code {
public string Title { get; set; }
}
One solution to do that is have a class that holds the component properties and pass the properties to it
<input #bind="_newTodo" />
<button #onclick="#AddTodoItem">+</button>
#foreach (TodoItem todoItem in _todoItemsDto)
{
// Pass the Dto properties to the component
<TodoItem Title="#todoItem.Title" />
}
#code {
private IList<TodoItemDto> _todoItemsDto = new List<TodoItemDto>();
private string _newTodo;
class TodoItemDto {
public string Title { get; set; }
}
private void AddTodoItem()
{
if (!string.IsNullOrWhiteSpace(_newTodo))
{
_todoItems.Add(new TodoItemDto { Title = _newTodo });
_newTodo = string.Empty;
}
}
}
I just built a Help system that has a LinkButton component, and I render it like this:
foreach (HelpCategory category in Categories)
{
<LinkButton Category=category Parent=this></LinkButton>
<br />
}
Each HelpCategory has one or more Help Articles that can be expanded.
Here is the code for my LinkButton, it does more of the same:
#using DataJuggler.UltimateHelper.Core
#using ObjectLibrary.BusinessObjects
#if (HasCategory)
{
<button class="linkbutton"
#onclick="SelectCategory">#Category.Name</button>
#if (Selected)
{
<div class="categorydetail">
#Category.Description
</div>
<br />
<div class="margintop">
#if (ListHelper.HasOneOrMoreItems(Category.HelpArticles))
{
foreach (HelpArticle article in Category.HelpArticles)
{
<ArticleViewer HelpArticle=article Parent=this>
</ArticleViewer>
<br />
<div class="smallline"></div>
}
}
</div>
}
}
Sometimes the obvious solutiton is simpler and better.
TodoItem:
<span>#Title</span>
#code {
[Parameter] // add this parameter to accept title
public string Title { get; set; }
}
Page:
<input #bind="_newTodo"/>
<button #onclick="#AddTodoItem">+</button>
<ol>
#foreach (var todoItem in _todoItems)
{
<li>
<TodoItem Title="#todoItem.Title"/>
</li>
}
</ol>
#code {
private readonly IList<TodoItem> _todoItems = new List<TodoItem>();
private string _newTodo;
private void AddTodoItem()
{
if (!string.IsNullOrWhiteSpace(_newTodo))
{
_todoItems.Add(new TodoItem { Title = _newTodo });
_newTodo = string.Empty;
}
}
}
Output:
This may not be the best way to do it but it will avoid having 50+ attributes to set in the tag.
Component :
<h1>#Title</h1>
<h2>#Description</h2>
#code {
public string? Title { get; set; }
public string? Description { get; set; }
[Parameter]
public KanbanTask? Origin //KanbanTask is how I named this same component
{
get { return null; }
set
{
Title = value?.Title;
Description = value?.Description;
}
}
}
Then how to call it :
#foreach (var todoTask in TodoList)
{
<KanbanTask Origin="#todoTask" />
}
This is using the set of a property has a constructor. It works, but I think it's not excellent since set was not made for it in the first instance. If anyone else has an idea to make it better I'm interested
Yes, of course you can render a list with foreach. This article covers it well.
Here is an example. Note the use of the item in the click event so you know which item was clicked on. Note that this must be done using a lambda.
<section data-info="List of images">
#foreach (var item in this.Parent.CurrentCard.Images.OrderByDescending(a => a.InsertedDate))
{
<div class="border border-secondary m-2">
<img class="img-fluid" src="/api/image/fetch/#item.StorageName" alt="#item. Filename">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
Remove
</div>
</div>
}

Edit view not being populated with objects data

I am quite new to ASP .Net, and could use some help... I have an ASP .Net Core 1.1 web app. In it, I have an "Edit" view for editing a simple object, which a corresponding controller calls when routed to it. This is the view:
#model InspectionsTestClient.Models.Property
#{
ViewData["Title"] = "Edit";
}
<h2>Edit</h2>
#Html.ValidationSummary();
<form asp-action="Edit">
<div class="form-horizontal">
<h4>Property</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="UnitNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="UnitNumber" class="form-control" />
<span asp-validation-for="UnitNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="BuildingName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="BuildingName" class="form-control" />
<span asp-validation-for="BuildingName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Street" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Street" class="form-control" />
<span asp-validation-for="Street" class="text-danger"></span>
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
This is the controller which calls that view:
// GET: Property/Edit/5
public ActionResult Edit(int id)
{
return View();
}
And this is the model:
namespace InspectionsTestClient.Models
{
//[Table("property")]
public class Property
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
[MaxLength(10, ErrorMessage = "Unit number too long")]
[Display(Name = "Unit #")]
public string UnitNumber { get; set; }
[MaxLength(45, ErrorMessage = "BuildingName name too long")]
public string BuildingName { get; set; }
[MaxLength(45, ErrorMessage = "Street too long")]
public string Street { get; set; }
}
}
So when I navigate to that page, the controller fires up, and returns the Edit view. I have confirmed the parameter "id" is populated. When the Edit view loads in the browser, however, all the input textboxes are empty. I would expect them to be pre-populated with the values for the object in question. What am I missing?
The issue you are experiencing is happening because you are not returning that object to the view.. actually in your case you're not even going out to the db to get the object.
You need to edit you Edit action to something like this:
// GET: Property/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var object = db.TableName.Find(id);
// db = connectionstring
// TableName = database table that holds the object that you want to return
if (object == null)
{
return HttpNotFound();
}
return View(object);
}
Let me know if this helps
public class PropertyController
{
private readonly ApplicationDbContext _dbContext;
public PropertyController(ApplicationDbContext dbContext){
_dbContext = dbContext;
}
//GET: Property/Edit/5
public async Task<IActionResult> Edit(int id)
{
var property = await _dbContext.Property.FirstOrDefaultAsync(p => p.Id == id);
return View(property);
}
}
If you don't pull the data from the database and send it to the view of course it will always be blank. Edit(int id) there will be 2, both slightly different from the other.
[HttpPost]
[ValidateAntiForgeryToken]
//Post: Property/Edit/5
public async Task<IActionResult> Edit(int id, [Bind("Id", "UnitNumber", "BuildingNumber", "Street")] Property property)
{
if(ModelState.IsValid){
}
else{
}
}
not everyting is present but that is part of your adventure.

I want to make sure my code meet the standard and security

Am new to ASP.NET and i just developed a simple online examination portal for learning.
I used ADO.NET,MySql and developed in VS 2010.
I have a login page in which user can login and register page for new user.After successful login user is redirected to the question page and i fetch the first question from database.
I populated the question in label and options in Radio Button list.User can select one option and click next button.
In the click event of next button i calculate the marks.
I store all values in session only.When user click next of last question that is 4 user is redirected to result page and print the marks.
This is my code
public partial class Questions : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
Response.Cache.SetNoStore();
if (!IsPostBack)
{
renderQuestions(1);
Session["buttonIndex"] = 1;
Session["Marks"] = 0;
}
}
public void renderQuestions(int index)
{
MySqlConnection con = null;
string conString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
string qry = "SELECT * FROM QUESTIONS WHERE QUESTION_ID="+index+"";
try
{
using (con = new MySqlConnection(conString))
{
con.Open();
using (MySqlCommand cmd = new MySqlCommand(qry, con))
{
using (MySqlDataAdapter ada = new MySqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
ada.Fill(dt);
if (dt.Rows.Count > 0)
{
clsQuestion ques = new clsQuestion();
ques.QuestionId = Convert.ToInt32(dt.Rows[0][0]);
ques.Question = Convert.ToString(dt.Rows[0][1]);
ques.Option1 = Convert.ToString(dt.Rows[0][2]);
ques.Option2 = Convert.ToString(dt.Rows[0][3]);
ques.Option3 = Convert.ToString(dt.Rows[0][4]);
ques.Option4 = Convert.ToString(dt.Rows[0][5]);
ques.Answer = Convert.ToInt32(dt.Rows[0][6]);
renderQuesAndAnswers(ques);
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
}
}
public void renderQuesAndAnswers(clsQuestion quest)
{
lblQuestion.Text = quest.Question;
RadioButtonList1.Items.Clear();
RadioButtonList1.Items.Add(quest.Option1);
RadioButtonList1.Items.Add(quest.Option2);
RadioButtonList1.Items.Add(quest.Option3);
RadioButtonList1.Items.Add(quest.Option4);
Session["QuestionNumber"] = quest.QuestionId ;
Session["Answer"] = quest.Answer;
}
public class clsQuestion
{
private int questionId;
private string question;
private string option1;
private string option2;
private string option3;
private string option4;
private int answer;
public int QuestionId
{
get { return questionId; }
set { questionId = value; }
}
public string Question
{
get { return question; }
set { question = value; }
}
public string Option1
{
get { return option1; }
set { option1 = value; }
}
public string Option2
{
get { return option2; }
set { option2 = value; }
}
public string Option3
{
get { return option3; }
set { option3 = value; }
}
public string Option4
{
get { return option4; }
set { option4 = value; }
}
public int Answer
{
get { return answer; }
set { answer = value; }
}
}
protected void option1_CheckedChanged(object sender, EventArgs e)
{
if (Convert.ToInt32 (Session["Answer"]) == 1)
{
int marks=Convert.ToInt32 (Session["Marks"]);
marks++;
Session["Marks"] = marks;
}
}
protected void option2_CheckedChanged(object sender, EventArgs e)
{
if (Convert.ToInt32(Session["Answer"]) == 2)
{
int marks = Convert.ToInt32(Session["Marks"]);
marks++;
Session["Marks"] = marks;
}
}
protected void option3_CheckedChanged(object sender, EventArgs e)
{
if (Convert.ToInt32(Session["Answer"]) == 3)
{
int marks = Convert.ToInt32(Session["Marks"]);
marks++;
Session["Marks"] = marks;
}
}
protected void option4_CheckedChanged(object sender, EventArgs e)
{
if (Convert.ToInt32(Session["Answer"]) == 4)
{
}
}
protected void btnNext_Click(object sender, EventArgs e)
{
}
protected void btnNext_Click1(object sender, EventArgs e)
{
int buton = Convert.ToInt32(Session["buttonIndex"]);
if (buton < 5)
{
if (RadioButtonList1.SelectedIndex + 1 == Convert.ToInt32(Session["Answer"]))
{
int marks = Convert.ToInt32(Session["Marks"]);
marks++;
Session["Marks"] = marks;
}
Session["buttonIndex"] = Convert.ToInt32(Session["buttonIndex"]) + 1;
renderQuestions(Convert.ToInt32(Session["buttonIndex"]));
if (buton == 4)
{
Server.Transfer("Results.aspx");
Session.RemoveAll();
}
}
}
}
this is my HTML
<form id="form1" runat="server">
<div>
<h3>Please choose the right answer</h3>
</div>
<table class="style1">
<tr>
<td class="style3">
<asp:Panel ID="Panel1" runat="server">
<asp:Label ID="lblQuestion" runat="server" Text=""></asp:Label>
</asp:Panel>
</td>
<td class="style4">
</td>
</tr>
<tr>
<td class="style2">
Answers:</td>
<td>
</td>
</tr>
<tr>
<td class="style2">
<asp:Panel ID="Panel2" runat="server">
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
</asp:RadioButtonList>
<asp:RadioButton ID="option1" runat="server" Checked="false" AutoPostBack="True"
GroupName="Option" oncheckedchanged="option1_CheckedChanged" />
<asp:RadioButton ID="option2" runat="server" Checked="false" AutoPostBack="True"
GroupName="Option" oncheckedchanged="option2_CheckedChanged" />
<asp:RadioButton ID="option3" runat="server" Checked="false" AutoPostBack="True"
GroupName="Option" oncheckedchanged="option3_CheckedChanged" />
<asp:RadioButton ID="option4" runat="server" Checked="false" AutoPostBack="True"
GroupName="Option" oncheckedchanged="option4_CheckedChanged" />
</asp:Panel>
</td>
<td>
</td>
</tr>
<tr>
<td class="style2">
</td>
<td>
</td>
</tr>
<tr>
<td class="style2">
<asp:Button ID="btnNext" runat="server" onclick="btnNext_Click1" Text="Next" />
</td>
<td>
</td>
</tr>
</table>
</form>
I got the result perfect and no issues yet.But i want to make sure am doing the best way and do my code meet the standards and is there any security issues.
Please some one guide me through this if u can.Thanks in advance.

How to check if item is selected in a dropdownList and enable/disable a textbox if a listitem is selected/not selected

I have a page where i have created a form of sorts.
I have 2 dropdownlists(profilelist & salarylist).
I have 3 textboxes in this form. What i want to do:
I have 2 boxes where i create a new profile and a new salarygroup and the new profile is added to the profillist amd the salarygroup is added to the salarylist.
Now I want the third box to be disabled UNTIL an item in both the salarylis and profillist is selected. once items are selected the textbox should be enabled.
My view:
#model KUMA.Models.EmployeeCardAdminModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="row bgwhite">
<div class="twelve columns">
<h2>Administration KUMA</h2>
<div class="row bgwhite">#using (Html.BeginForm("Index", "Admin"))
{
<div class="three columns">
#Html.DropDownList("UserId", (SelectList)ViewBag.UserId, "--Välj anställd--")
</div>
<div class="three columns" style="margin-right:457px !important;">
#Html.DropDownList("Salaryid", (SelectList)ViewBag.Salaryid, "--Välj LöneGrupp--")
<input style="float:left;" type="submit" value="Knyt" />
</div>
}
#using (Html.BeginForm("Kompetens", "KumaAdmin"))
{
<div class="three columns" style="margin-right: 627px;">
<h6>Kompetenser</h6>
<div style="width:456px;"> #Html.ListBox("kompetensId", (SelectList)ViewBag.KomId, new { placeholder = "Kompetenser" })</div><br/>
#Html.TextBoxFor(mm => mm.Kompetens, new { placeholder = "Ange Kompetens" })
#*#Html.TextBoxFor(mm => mm.KompetensTest, new { placeholder = "Kompetens" })
#Html.TextAreaFor(mm => mm.KompetensTest, new { placeholder = "Kompetens", rows="5", cols="80" })*#
<input type="submit" style="margin-right: 205px;" value="Skapa"/><br/><br/>
</div>
}
#using (Html.BeginForm("Index", "KumaAdmin"))
{
<div class="three columns" style="margin-right: 627px;">
#* <input name="profileTxtBox"type="text" style="width:97px; height:28px;" value="" />*#
#Html.TextBoxFor(mm => mm.Profile, new { placeholder = "Ange Profil" })
#Html.TextBoxFor(mm => mm.SalaryGroup, new { placeholder = "Ange LöneGrupp" })
<input type="submit" value="Skapa"/>
</div>
}
#* <div class="one columns" style=" margin-left: 100px;margin-right: 164px; margin-top: -33px;">
<input name="profileTxtBox"type="submit" style="width:100px;" value="Add" />
</div>*#
<div class="five columns"></div>
</div>
</div
>
Controller:
public class AAdminController : Controller
{
static List<Employee> list = new List<Employee>();
//EmployeeCardAdminModel employee = new EmployeeCardAdminModel();
//
// GET: /Admin/
//[Authorize(Roles = "Admin")]
[HttpGet]
public ActionResult Index()
{
ViewBag.UserId = new SelectList(list, "Id", "Profile");
ViewBag.Salaryid = new SelectList(list, "Id", "SalaryGroup");
ViewBag.KomId = new SelectList(list, "Id", "Kompetens");
ModelState.Clear();
return View("Index");
}
[HttpPost]
// submit for profile & salary box
public ActionResult Index(Models.EmployeeCardAdminModel e)
{
if (string.IsNullOrEmpty(e.Profile) == false && string.IsNullOrEmpty(e.SalaryGroup) == false)
{
// adda a new employye to the list and set the values from the parameter to the model
list.Add(new Employee
{
Id = e.Id + 1,
Profile = e.Profile,
SalaryGroup = e.SalaryGroup
});
}
return (Index());
}
[HttpPost]
// submit for knowledge box
public ActionResult Kompetens(Models.EmployeeCardAdminModel e)
{
if (string.IsNullOrEmpty(e.Kompetens) == false)
{
// adda a new employye to the list and set the values from the parameter to the model
list.Add(new Employee
{
Kompetens = e.Kompetens
});
}
return (Index());
}
And finally my model(note that the emplyee class is the same as my model, with the same properties but ive read that for best practice it is best to separate these.):
public class EmployeeCardAdminModel
{
public string Profile { get; set; }
public int Id { get; set; }
public string SalaryGroup { get; set; }
public string Kompetens { get; set; }
}
the way i would normaly do this is to call the desired lists and check if the selected index is larger than null but the problem is i don't know how to access the list from the controller in the correct way so i can get access to the items in it. also how can i get an id on the textboxes? I need this to be able to disable/enable the correct textbox.
Im pretty new to mvc and i learn by doing projects so all advice is appreciated.
Thank you!
Well after some time I realized that there wasn't a good way of doing this without script.
So i solved it with jquery like this:
$(function () {
$(".list select").change(function () {
if ($(".list1 select").val().length == 0 || $(".list2 select").val().length == 0) {
$(".kompetensbox input").attr('disabled', 'disabled');
}
else {
$(".kompetensbox input").removeAttr('disabled');
}
})
});
view changes (added css classes):
<div class="three columns list list1">
#Html.DropDownList("UserId", (SelectList)ViewBag.UserId, "--Välj profilgrupp--")
</div>
<div class="three columns list list2" style="margin-right:457px !important;">
#Html.DropDownList("Salaryid", (SelectList)ViewBag.Salaryid, "--Välj LöneGrupp--")
<input style="float:left;" type="submit" value="Knyt" />
</div>
Hope it helps others that attempt the same.