Checkbox and controllers - c#

I have one Model Having two virtual Properties i.e
public virtual IEnumerable MediumIds { get; set; }
public virtual IEnumerable AnsLanguageIds { get; set; }
I have Used ViewBag To Populate Them i.e
ViewBag.MediumIds = db.ExamMediums.Where(x => x.ExamId == _ExamId).Select(x => x.Medium);
ViewBag.AnsLanguageIds = new SelectList(db.AnswerLanguages.ToList(), "AnswerLanguageId", "AnsLanguage");
And My View Is
#foreach (var item in
ViewBag.MediumIds)
{
<input id="MediumIds" name="MediumIds" value="#item.MediumId" type="checkbox" /><strong>
#item.Medium1 </strong>
#Html.DropDownList("AnsLanguageIds")
<br />
}
I want The functionality like when the checkbox is selected than only the the dropdown should be enabled else it should be disabled and also i want that for which medium which anslanguage is selected
Your answer will be appreciated.

You can make the drop down lists disabled by default by passing new { disabled = "disabled" } as the DropDownList() method's htmlAttributes argument. This JQuery should toggle the select's disabled state when each checkbox is checked:
$(function() {
$("input#MediumIds").click(function() {
var checkbox = $(this);
var dropDownlist = checkbox.sibling("select:first");
dropDownlist.attr("disabled", checkbox.is(":checked") ? "" : "disabled");
});
});
...I'm not sure what you mean by "i want that for which medium which anslanguage is selected"?

Related

Using ViewBag with #Html.CheckBoxFor rather than "plain" <input type= "checkbox">

Having already used #Html.CheckBoxFor within a View, I plan to use with the former Tag Helper in conjunction to ViewBag within the same View to circumvent few errors (e.g. variable definition):
MODEL
public class test
{
public int ItemID { get; set; }
public string ItemName { get; set; }
public bool IsAvailable { get; set; }
}
CONTROLLER
List<test> ItemList = new List<test>();
ItemList.Add(new test {ItemID=1, ItemName="apple", IsAvailable = false});
ItemList.Add(new test {ItemID=2, ItemName="mango", IsAvailable = false});
ItemList.Add(new test {ItemID=3, ItemName="stuck", IsAvailable = false});
ItemList.Add(new test {ItemID=4, ItemName="blocked", IsAvailable = false});
ItemList.Add(new test {ItemID=5, ItemName="help:(", IsAvailable = false});
ViewBag.ItemList = ItemList;
VIEW
<table>
#foreach (var item in ViewBag.ItemList)
{
<tr><td>
<input type= "checkbox" id = "Check_#item.ItemID" checked="#item.IsAvailable"
onclick="CheckOnlyOneCheckBox(this);"/>
<label for="Check_#item.ItemID">#item.ItemName</label>
</tr>
}
</table>
2 main issues have been encountered:
(a) Value of the selected box could not retrieved from a submit button using
foreach (var item in ViewBag.ItemList)
{
if (item.IsCheck)
{
var zz = item.ItemName;
}
}
(b) format of the displayed ItemName using <input type= "checkbox"> look slightly different (e.g. bold font) than the ones obtained from a previous checkbox list using #Html.CheckBoxFor.
Thus any assistance in using #Html.CheckBoxFor with ViewBag would highly be appreciated.
EDIT
#Md Farid Uddin Kiron
The main issue lies on the fact that a checkbox list has already been defined (in the same same View) via:
List<test> chk = new List<test>();
chk.Add(new test() {ReferalTypeId=1, ReferalTypeName = "box1",
IsReferalCheck=false});
chk.Add(new test() {ReferalTypeId=2, ReferalTypeName =
"box2", IsReferalCheck=false});
chk.Add(new test() {ReferalTypeId=3, ReferalTypeName =
"Other", IsReferalCheck=false});
CtrList chklist = new CtrList(); // Ctrl being a public class defined
// in MODEL
chklist.reflist = chk;
return View(chklist);
Empirically I've ended up to a situation, where I could not define within public IActionResult Index() another checkbox list returning something else than chklist since the variable (e.g. list) won't be defined while looping it from View.
As a result I had to use, as a way around: ViewBag, enabling me to pass variable from Model to View without any problem. Without binding it, this effective way around has been raising another issue and the solution of last resort I am investigating consists of:
(a) looping through the checkbox;
(b) identifying the selected value via ViewBag;
(c) then finding a way to pass the selected variable from View to Controller. However, I had to concede that this latter approach looks sub-optimal.
Best
I have researched a lot on your scenario. The way you planned it cannot execute well because we cannot set htmlAttributes on CheckBoxFor so in this way we cannot retrive value from the from CheckBoxFor as you might know to get value from submitted item we need to set htmlAttributes on it like id class or name
So considering your scenario the easiest solution I have founded for you like below:
Your Predefined Model:
public class CheckBoxTestModel
{
public int ItemID { get; set; }
public string ItemName { get; set; }
public bool IsAvailable { get; set; }
}
View Model To Lead Check On View:
public class CheckBoxFromViewBagModel
{
public List<CheckBoxTestModel> CheckBoxes { get; set; }
}
Controller On Load:
public IActionResult CheckboxforFromViewBag()
{
var checkBoxList = new List<CheckBoxTestModel>()
{
new CheckBoxTestModel() { ItemID=1,ItemName="apple", IsAvailable = false },
new CheckBoxTestModel() { ItemID=2,ItemName="mango", IsAvailable = false },
new CheckBoxTestModel() { ItemID=3,ItemName="stuck", IsAvailable = false },
new CheckBoxTestModel() { ItemID=4,ItemName="blocked", IsAvailable = false },
new CheckBoxTestModel() { ItemID=5,ItemName="help:(", IsAvailable = false },
};
var model = new CheckBoxFromViewBagModel();
model.CheckBoxes = checkBoxList;
return View(model);
}
View When Load CheckBox:
#model CheckBoxFromViewBagModel
#{
ViewData["Title"] = "CheckboxforFromViewBag";
}
<h4>Load CheckBox From ViewModel & Submit value to Controller wtih Selected Value</h4>
<hr />
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
</style>
#using (Html.BeginForm("SubmitValueFromCheckBoxList", "UserLog"))
{
<table class="table-bordered">
<tr>
<th>Item Name</th>
<th>Is Checked</th>
</tr>
#for (int i = 0; i < Model.CheckBoxes.Count; i++)
{
<tr>
<td> #Model.CheckBoxes[i].ItemName</td>
<td> #Html.CheckBoxFor(r => Model.CheckBoxes[i].IsAvailable)</td>
#Html.HiddenFor(h => #Model.CheckBoxes[i].ItemID)
#Html.HiddenFor(h => #Model.CheckBoxes[i].ItemName)
</tr>
}
</table>
<br />
<input id="Button" type="submit" value="Submit To Controller" class="btn btn-primary" />
}
Controller When Submit The Value:
[HttpPost]
public IActionResult SubmitValueFromCheckBoxList(CheckBoxFromViewBagModel checkBoxViewModel)
{
var checkBoxValueFromView = checkBoxViewModel;
return Ok(checkBoxValueFromView);
}
Output:
Note: As per your scenario I think this would the eligant way to handle this. Other than either of the work around bring us another
chanllenge. In my solution you can ignore the CSS part. Here the important and tricky part is #Html.HiddenFor(h => #Model.CheckBoxes[i].ItemID) #Html.HiddenFor(h => #Model.CheckBoxes[i].ItemName) sets htmlAttributes for us.
I hope it would help you well.

Add textboxes dynamically in ASP.NET MVC

I work on an ASP.NET MVC project that I need some help with. I need to be able to create x number of textboxes when the user click "add textbox". When the user enter the page a viewmodel is loaded. This viewmodel need to handle the x number of textboxes that the user create when he is on the page so that when the page is posted these textboxes are part of the model. The model should look something like this..
public class PlanViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public List<EventViewModel> EventList { get; set; } // this should be the list of textboxes that the user "create" by clicking add new
}
public class EventViewModel
{
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Description { get; set; }
}
I'm kinda lost on how to do this so any help is appreciated.
UPDATE
I've added this javascript that add textboxes client side..
<script type="text/javascript">
function GetDynamicTextBox(value) {
return('<input type="text" name="events[0].Key" value="box1" /><input type="text" name="events[0].Value.StartDate" value="box2"/><button type="button" class="btn btn-sm btn-primary" onclick="RemoveTextBox(this)"><i class="fa fa-angle-right"></i> Remove</button>');
}
function AddTextBox() {
var div = document.createElement('DIV');
div.innerHTML = GetDynamicTextBox("");
document.getElementById("divcontent").appendChild(div);
}
function RemoveTextBox(div) {
document.getElementById("divcontent").removeChild(div.parentNode);
}
</script>
<div id="divcontent" class="form-group">
<button type="button" class="btn btn-sm btn-primary" onclick="AddTextBox()"><i class="fa fa-angle-right"></i> Add</button>
</div>
I think I only need to add unique id's for the textboxes like this...
events[0].Key
events[1].Key
events[2].Key
and so on..
But I don't know how. Anyone knows?
You can add a list of String, like this
public String[] MyTextFields
and then create HTML using Javascript, like this:
<input name="myTextFields[0]"></input>
<input name="myTextFields[1]"></input>
In Razor view:
#for (var i = 0; i < Model.EventList.Count; i++)
{
#Html.EditorFor(x => Model.EventList[i].Name)
}
To set the name attribute of all edited elements in javascript, this is to be called on page load, and any time the collection changes (item is added or removed):
var children = document.getElementById("myDIV").children; // TODO: here supposing children are the input elements, may be different on your page (they may be nested in a different way)
for (i = 0; i < children.length; i++)
{
var el = children[i];
el.name = 'EventList[' + i + '].Name'; // TODO: look into source code of the generated page for the actual format of existing elements and then modify the mask accordingly
el.id = 'EventList[' + i + '].Name';
}
If it is ok to have JS dependency than I suggest to use light Knockout library. It will help you to create/edit/delete your inputs. Check example in JS fiddle.
Use HTML to adjust your view. Tag data-bind lets you to bind to data and events
<button data-bind="click: addInput">Add</button>
<div data-bind="foreach: inputs">
<input data-bind="value: text"/><br />
</div>
<button data-bind="click: proceed">Proceed</button>
<!-- Use Knockout JS library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>
Then small JS script which handles adding new input and processing data on click.
function InputData(text) {
let self = this;
self.text = text;
}
function InputViewModel() {
let self = this;
// Your array of HTML inputs
self.inputs = ko.observableArray([new InputData("Default value")]);
self.output = ko.observable();
self.addInput = function() {
// Dynamically adds new input on user click button "Add"
self.inputs.push(new InputData(""));
};
self.proceed = function() {
// Process all input with their values
for (var i = 0; i < self.inputs().length; i++) {
console.log(self.inputs()[i].text);
}
}
}
// Bind our JS to HTML view
ko.applyBindings(new InputViewModel());

How to validate dynamic controls in .net core

I am creating the survey application for which I am creating the controls dynamically(Like checkbox,radio-button,textbox etc).
Each question will have the controls depending upon the control type assigned to the question and on question type the answer choices(checkbox, radio button) will be rendered.
On Next/Previous navigation I am storing current page answers in the database. While navigating the page I am doing ajax call for database saving and my UI/controls are NOT in the form.
I have created ViewModel based on my LMS_SurveyQuestions and LMS_SurveyQuestionOptionChoice table.
So, while creating the UI in view in for loop, I have directly assigned SurveyQuestionOptionChoiceID as Control ID while creating the AnswerChoice controls and stored the same in the table SurveyUserAnswer table.
Model
public class LMS_TraineeSurveyPaginationViewModel
{
public List<LMS_SurveyQuestions> SurveyQuestions { get; set; }
public List<LMS_SurveyQuestionOptionChoice> SurveyQuestionOptionChoice { get; set; }
public SurveyPager Pager { get; set; }
}
and this is how I rendered the view
#foreach (var item in Model.SurveyQuestions)
{
foreach (var data in Model.SurveyQuestionOptionChoice.Where(x => x.SurveyQuestionID == item.SurveyQuestionID).ToList())
{
if (item.QuestionTypeID == QuestionType.RadioButton)
{
<li style="list-style:none;">
<input type="radio" name="rb" id="#data.SurveyQuestionOptionChoiceID" />
<span>#data.OptionChoice</span>
</li>
}
else if (item.QuestionTypeID == QuestionType.CheckBox)
{
<li style="list-style:none;">
<input type="checkbox" id="#data.SurveyQuestionOptionChoiceID" name="#data.SurveyQuestionOptionChoiceID" " />
<span>#data.OptionChoice</span>
</li>
}
}
}
and while saving the answer into database I have created the JSON/JS array as model for SurveyUserAnswer and saved it into database as follows. Below is example for radio button
function SaveValues() {
var surveyQuestion = #Html.Raw(Json.Serialize(Model.SurveyQuestions.ToArray()));
var surveyQuestionOptionChoide = #Html.Raw(Json.Serialize(Model.SurveyQuestionOptionChoice.ToArray()));
for (item in surveyQuestion) {
var surveyQuestionID=surveyQuestionViewModel[item].SurveyQuestionID;
var filteredData = surveyQuestionOptionChoide.filter(function(filteredItem) {
return (filteredItem.SurveyQuestionID==surveyQuestionID);
});
for (optionChoice in filteredData) {
if(surveyQuestion[item].QuestionTypeID=='#QuestionType.RadioButton') {
if (($('#'+SurveyQuestionOptionChoiceID).prop("checked"))) {
surveyUserAnswer.push({ SurveyUserAnswerID: filteredData[optionChoice].SurveyUserAnswerID==null?0:filteredData[optionChoice].SurveyUserAnswerID,
SurveyQuestionOptionChoiceID: SurveyQuestionOptionChoiceID,SurveyUserID:'#ViewBag.SurveyUserID',AnswerText:null,
MarksObtained:filteredData[optionChoice].Marks,WhenCreated:'#DateTime.UtcNow',WhoCreated:'#tenant.UserID'});
}
}
}
}
$.post('#Url.Action("GetTraineeSurvey", "Survey")', {SurveyID:surveyID,page:page, surveyUserAnswer: surveyUserAnswer,PrevBranchQuestionPage:currentPage,IsBranchQuestionAvailable:IsBranchQuestionAvailable }, function (data) {
$('#surveyModalContent').html('');
$('#surveyModalContent').html(data);
$("#surveyModal").modal('show');
}).fail(function() {
alert( "error in GetTraineeSurvey" );
}).success(function() { });
}
So, my question is how can I validate dynamically created controls in this scenario ?
You can use Unobtrusive jQuery validation basic on data attributes on controls.
Read more about that on this LINK.

MVC DropDownList OnChange to update other form fields

I am new to MVC (I am moving over from the dark side of traditional ASP.Net) and I know that SO is more of a "why doesn't this work" but, being new to MVC, I just wanted to ask how something is achieved - I don't really have any code or markup because I don't know how at the moment.
Right, using an analogous example... I have a form that has a drop-down of a list of "Widgets" (have that working, thanks to SO) ... and then there are other fields (Length/Height/Width) which have "default" values.
When the form displays, the Drop-Down is shown but the form fields of L/H/W are empty/disabled until the user selects one from the DDL.
Now, in clasic ASP.Net world, you would do a PostBack on the "onselectedindexchange" and that would look at the item selected, then update the L/H/W fields with values from the "master widget entry" version.
As MVC does not have post back... how is this achieved?
In Asp.Net MVC, There is no postback behaviour like you had in the web forms when a control value is changed. You can still post the form and in the action method, you may read the selected value(posted value(s)) and load the values for your text boxes and render the page again. This is complete form posting. But there are better ways to do this using ajax so user won't experience the complete page reload.
What you do is, When user changes the dropdown, get the selected item value and make a call to your server to get the data you want to show in the input fields and set those.
Create a viewmodel for your page.
public class CreateViewModel
{
public int Width { set; get; }
public int Height{ set; get; }
public List<SelectListItem> Widgets{ set; get; }
public int? SelectedWidget { set; get; }
}
Now in the GET action, We will create an object of this, Initialize the Widgets property and send to the view
public ActionResult Create()
{
var vm=new CreateViewModel();
//Hard coded for demo. You may replace with data form db.
vm.Widgets = new List<SelectListItem>
{
new SelectListItem {Value = "1", Text = "Weather"},
new SelectListItem {Value = "2", Text = "Messages"}
};
return View(vm);
}
And your create view which is strongly typed to CreateViewModel
#model ReplaceWithYourNamespaceHere.CreateViewModel
#using(Html.BeginForm())
{
#Html.DropDownListFor(s => s.SelectedWidget, Model.Widgets, "Select");
<div id = "editablePane" >
#Html.TextBoxFor(s =>s. Width,new { #class ="myEditable", disabled="disabled"})
#Html.TextBoxFor(s =>s. Height,new { #class ="myEditable", disabled="disabled"})
</div>
}
The above code will render html markup for the SELECT element and 2 input text fields for Width and Height. ( Do a "view source" on the page and see)
Now we will have some jQuery code which listens to the change event of the SELECT element and reads the selected item value, Makes an ajax call to server to get the Height and Width for the selected widget.
<script type="text/javascript">
$(function(){
$("#SelectedWidget").change(function() {
var t = $(this).val();
if (t !== "") {
$.post("#Url.Action("GetDefault", "Home")?val=" + t, function(res) {
if (res.Success === "true") {
//enable the text boxes and set the value
$("#Width").prop('disabled', false).val(res.Data.Width);
$("#Height").prop('disabled', false).val(res.Data.Height);
} else {
alert("Error getting data!");
}
});
} else {
//Let's clear the values and disable :)
$("input.editableItems").val('').prop('disabled', true);
}
});
});
</script>
We need to make sure that we have an action method called GetDetault inside the HomeController to handle the ajax call.
[HttpPost]
public ActionResult GetDefault(int? val)
{
if (val != null)
{
//Values are hard coded for demo. you may replae with values
// coming from your db/service based on the passed in value ( val.Value)
return Json(new { Success="true",Data = new { Width = 234, Height = 345}});
}
return Json(new { Success = "false" });
}
Make a Controller "Action" that return "Json" data.
Make Ajax call "onchange" of dropdown to that "Action".
On ajax "response" (json) u will get values then set those values to
fields from json response.
This is the way to update field values.
Shyju made a brilliant post in 2015 but I had to update it to make it work for MVC 5. I worked with one of my progammers (I'm an IT manager) to create this. You need to create a class to represent the dropdown and the Height and Width.
public class AjaxText
{
public int Width { set; get; }
public int Height { set; get; }
public List<SelectListItem> Widgets { set; get; }
public int? SelectedWidget { set; get; }
}
In my HomeController.cs, the GET action will create an object of this, initialize the Widgets property and send to the view.
public IActionResult AjaxText()
{
//Hard coded for demo. You may replace with data form db.
AjaxText vm = new AjaxText();
vm.Widgets = new List<SelectListItem>
{
new SelectListItem {Value = "1", Text = "Weather"},
new SelectListItem {Value = "2", Text = "Messages"}
};
return View(vm);
}
And your create view will render html markup for the SELECT element and 2 input text fields for Width and Height. ( Do a "view source" on the page and see)
#model AjaxText
#{
ViewData["Title"] = "AjaxText";
}
<h1>#ViewData["Title"]</h1>
#using(Html.BeginForm())
{
#Html.DropDownListFor(s => s.SelectedWidget, Model.Widgets, "Select");
<div id = "editablePane" >
#Html.TextBoxFor(s =>s. Width,new { #class ="myEditable", disabled="disabled"})
#Html.TextBoxFor(s =>s. Height,new { #class ="myEditable", disabled="disabled"})
</div>
Now we will have some code which listens to the change event of the SELECT element and reads the selected item value, makes an ajax call to server to get the Height and Width for the selected widget. I added some alerts to help you debug.
<script type="text/javascript">
$(function(){
$("#SelectedWidget").change(function() {
var t = $(this).val();
if (t !== "")
{
$.ajax({
type: 'POST',
datatype: 'json',
url: '/Home/GetDefault?val=' + t,
success: function (bbb) {
alert(t);
alert(bbb.success);
alert(bbb.info.height);
$("#Width").prop('disabled', false).val(res.Data.Width);
$("#Height").prop('disabled', false).val(res.Data.Height);
},
error: function (msg) {
alert("error");
}
});
} else {
//Let's clear the values and disable :)
$("input.editableItems").val('').prop('disabled', true);
}
});
});
</script>
And in my home controller, the Post is done almost the same as how Shyju did it, but success doesn't have quotes around true and false. And you don't have to use the word data... info or whatever will work too. But keep it lowercase to maintain your sanity.
[HttpPost]
public JsonResult GetDefault(int? val)
{
if (val != null)
{
//Values are hard coded for demo. you may replae with values
// coming from your db/service based on the passed in value ( val.Value)
return Json(new { success = true, info = new { width = 234, height = 345 } });
}
return Json(new { Success = false });
}
I'm sure there are better ways to do this. This is what worked for us. Cheers and enjoy your coding experience! :)

Use simple MVC Html.DropDownList to control visibility of a div, onLoad and on selectChange

I have the following code:
<div class="form-group">
<label class="col-xs-3 control-label">Intermediary Bank Required?:</label>
<div class="col-xs-9">
<p class="form-control-static">#Html.DropDownList("IntermediaryRequired",(SelectList)ViewBag.IntermediaryRequired,"NO", new { #class = "form-control" })</p>
</div>
</div>
IntermediaryRequired is a bool field on my model
I also have this Extension Helper:
public static class BooleanExtensions
{
public static string ToYesNoString(this bool value)
{
return value ? "YES" : "NO";
}
public static string ToDislay(this bool value)
{
return value ? "normal" : "none";
}
public static string ToChar(this bool value)
{
return value ? "1" : "0";
}
}
My aim is to hide/display a <div> in response to the selected value in the DropDownList for two cases:
when the user Manually changes the DropDownList selection
when the form loads with an existing value for the model field IntermediaryRequired
Please how can we achieve this.
You should be able to do this with a little bit of javascript. Listen to the change event of the dropdown, check the value and hide/show the div. do the samething on document.ready (page loaded) as well to work with existing value of the model.
<script type="text/javascript">
$(function(){
//On page load, update the visiblity
var v=$("#IntermediaryRequired").val();
UpdateDivVisibility(v);
//When user changes the dropdown, update visibility
$("#IntermediaryRequired").change(function(e){
var v=$("#IntermediaryRequired").val();
UpdateDivVisibility(v);
});
});
function UpdateDivVisibility(isVisible)
{
if(v=="YES")
{
$("#DivIdtoHide").show();
}
else
{
$("#DivIdtoHide").hide();
}
}
</script>
EDIT : As per the question in the comment
Usually I create a viewmodel like this
public class CreateCustomerVM
{
public string Name { set;get;}
public List<SelectListItem> IntermediaryOptions {set;get;}
public string IntermediaryRequired {set;get;}
public CreateCustomerVM()
{
this.IntermediaryOptions =new List<SelectListItem>()
}
}
and in your GET actions for create
public ActionResult create()
{
var vm = new CreateCustomerVM();
vm.IntermediaryOptions = GetOptions();
return View(vm);
}
private List<SelectListItem> GetOptions()
{
return new List<SelectListItem>
{
new SelectListItem {Value = "0", Text = "No"},
new SelectListItem {Value = "1", Text = "Yes"}
};
}
And your view will be bounded to the viewmodel
#model CreateCustomerVM
#using(Html.Beginform())
{
<div>
<p>Required?</p>
<p>#Html.DropdowListFor(s=>s.IntermediaryRequired,Model.IntermediaryOptions)
<div id="ExtraOptions">
<!-- Your additional UI elements here -->
</div>
<input type="submit" />
</div>
}
In your Form post, you can read the IntermediaryRequired value and convert that to boolean value
[HttpPost]
public ActionResult Create(CreateCustomerVM model)
{
//check model.IntermediaryRequired
// to do : Save and Redirect(PRG pattern)
}
You can do something like this to show/hide the div when the user Manually changes the Drop Down
var yourDiv = $('#yourDiv');
$('#IntermediaryRequired').on('change', function(){
if ($(this).val() == 'YES') {
yourDiv.show();
}
else {
yourDiv.hide();
}
});
And to get the same result on page load you can try
#if (Model.value)
{
<div id="yourDiv">
....
</div>
}
As a side note use p only when you want to add a paragraph, if you just want to add -meaningless- block element, you can use a div. You can read more about semantics here.

Categories

Resources