Display options value related to selected option in mvc4 on view - asp.net-mvc-4

I am making a form. I want to display the options only related to the selected option, which select the user.
Select Degree
<select id="Degree">
#foreach (var v in Model.deg)
{
<option value=#v.Degree_Title>
#v.Degree_Title
</option>
}
</select>
for example if the user selects the degree It only it related options will display on the next select box. Kindly response me soon.

When you select a Degree (try to put it in DropDown in controller) and on select do autopostback which will populated the options related to selected degree.
Include this in javascript
function CausePostBack() {
//alert('hello');
var form1 = document.forms[0];
if (!form1.onsubmit || (form1.onsubmit() != false)) {
//alert('hello again');
form1.submit();
}
}
and for the DropDown
#Html.DropDownList("SomeName", (SelectList)ViewBag.ABC, new { #class = "DropDownList W150 ", onchange = "return CausePostBack();", value = #ViewBag.SelectedVal })

Related

Cant pass value from one view model to another in aurelia

I have two views, in view two i have a select option in which if the user selects an option i would want it to be passed to view one.
this is what i tried
view 1 ts
public selectedOption:string;
view 1 html
<template>
<require from="../../Options/Options"></require>
<options selected-option.bind="optionTypes.selectedOption" view-model.ref="OptionTypes"></options>
</template>
view 2 that i am loading in view 1
ts
export class optionTypes extends Component {
#bindable selectedOption: string = '';
sOptions = ["1", "2", "3"];
async displayOption() {
if (this.selectedOption == "1") {
//gets the option selected
}
}
html
<select md-select value.bind="selectedOption">
<option value="">choose a option</option>
<option repeat.for="type of sOptions" value.bind="type">${type}</option>
</select>
<a md-button="flat: true;" md-waves="color: accent;" class="modal-action btn-custom-width " click.delegate="displayOption()">proceed</a>
the select html loads correctly in the view one.The only issue is that its not returning the value that the user selected in the selectOption.how do i get the value from view 2 in view 1?
i tried this option also but the selectedOption in view 1 is always undefined

How to add a class to a specific selected li element in *ngFor

I have the following html snippets
<ul>
<li *ngFor="let report of searchResult.reports let i = index;">
<input type="checkbox" [(ngModel)]="report.reportChecked" (click)="selectedReport(report, i)">
<p kf-text weight="heavy" [ngClass]="{'bgColor': showBgd}">{{ report.name }}</p>
</li>
</ul>
And
<ul>
<li *ngFor="let language of languages" (click)="selectedLang(language)">
{{ language.name }}
<li>
<ul>
When I click on a particular report or reports and then select a language, I need to add the class bgColor to the report or reports which does not have that language.
Example: I have 3 reports: Report 1(english) , Report 2(spanish) , Report 3(english, french)
And 3 languages: English, Spanish, French
If i check Report 1 and Report 2 which are available only in English and Spanish respectively and from the drop down I choose the language English, the class bgColor needs to be added to Report 2 as it is not available in the chosen language, in this case english. If I check Report 1 and Report 3 and language spanish is chosen, the class bgcolor needs to be added to both Report 1 and Report 3 elements. If English was chosen, the class will not be added to any element since both are available in english. Bottom line, whichever report is checked, if it is not available in the chosen language, the class bgColor is to be added. If it is available class will not be added. Reports can be checked or unchecked at will.
The following is the typescript snippet
selectedReport(report, index) {
if(report.reportChecked) {
this.selectedReports.push({
type: report.type,
name: report.name,
reportChecked: report.reportChecked
});
this.indexItems.push(index);
} else {
this.selectedReports = _.reject(this.selectedReports, (el) => {
return el.type === report.type;
});
let indexRemove = this.indexItems.indexOf(index);
if(indexRemove > -1) {
this.indexItems.splice(indexRemove, 1);
}
}
}
selectedLang(language) {
let reportType;
let reportLanguage;
this.selectedLanguage = language;
this.selectedReports.forEach((report) => {
if (report.reportChecked) {
reportType = this.reportsWithLang.find((checkedReport) => {
return checkedReport.type === report.type;
});
reportLanguage = reportType.languages.find((language) => {
return language.id === this.selectedLanguage.id;
});
if(!reportLanguage) {
this.showBgd= true;
} else {
this.showBgd= false;
}
}
});
}
In my current implementation, When Report 1 is checked and language English is chosen the bgColor class is not added. But if language other than English, example, spanish is chosen the bgColor class is added to all report elements even though only Report 1 is checked. Again keeping Report 1 checked and language chosen as spanish, if Report 2 is now checked, the class bgColor is removed from all elements although the class should be added to Report 1 element. I tried a lot of different ways but still could not come up with a solution. Any help on this will be mightily appreciated.
The main problem is that showBgd is a component function, so it is a single value that is the same for all instances in the list. Ideally, you would assign a showBgd for each report in the selectedLang function and selectedReport function, but you are not referencing the same objects (which might also be true with the reportsWithLang and searchObject.reports.
So the best way to do this is probably to use a reportHasLanguage function to calculate for each listItem where the background color should show.
In your view, change
[ngClass]="{'bgColor': showBgd}"
to
[ngClass]="{'bgColor': reportHasLanguage(report, selectedLanguage)}"
then, in your component, add a function:
reportHasLanguage(report, language) {
// logic that can determine from a specific report object and the
// component level selectedLanguage object whether the BG Color
// should be on
return true; // for BG color on, false for off
}
I would fill in that logic for you, but I'm not sure what it is -- I don't know how the objects are constructed or how you have built the reportsWithLang object or the searchObject.reports object.
RE Comments Below: It might be easier to simplify the internal logic with something that tracks the selected objects by collection (rather than a flag on the object. If you do that, you can do something like:
toggleReportSelected(report) {
let idx = this.selectedReports.indexOf(report);
if (idx < 0) this.selectedReports.push(report)
else this.selectedReports.splice(idx,1)
}
findReports(searchParams) {
this.foundReports = this.reports.find( report) => {
return // logic matching report to searchParams
});
}
reportIsSelected(report) {
return this.selectedReports.indexOf(report) >= 0;
}
This approach allows you to use whatever trigger you want to toggle a report selected or not and you can always access all the properties of the selected report within the collections that your application is using. You can also tie a checkbox value to reportIsSelected if you want, or you can use other fancier ways of showing that it is selected.

How update view depending on user selection on Asp.Net core

I want to be able to display a form which changes depending on the value of a select on Dot.Net Core. I've seen many things like dynamic forms, View Components, razor and partials and also there is a lot of info out there but very confusing. Any info about the proper way to do what I want would be very appreciated.
I Have Categories>SubCategories>>Products
An order can be for one Category>>SubCategory only. So I want to display a select and depending on what category the user selects for the new Order, the products that I have to display. So I dont want to pick the user selection and go back to the controller and back to the view again and so on. I want to be able to dynamically display data according to the user selection.
Here an extract of the code just to briefly figure out what Im doing..I am not pasting the classes like Products,etc..
public class OrderCreateViewModel
{
public IEnumerable<Category> Categories { get; set; }
public IEnumerable<Branch> Branches { get; set; }
public int BranchId { get; set; }
public int CategoryId { get; set; }
}
Controller :
[HttpGet]
public IActionResult Create()
{
//Create vm
IEnumerable<Branch> branchList = _branchDataService.GetAll();
IEnumerable<Category> categoryList = _categoryDataService.GetAll();
OrderCreateViewModel vm = new OrderCreateViewModel
{
Categories = categoryList,
Branches = branchList
};
return View(vm);
}
View:
#model OrderCreateViewModel
<p>Create New Order </p>
<form asp-controller="Order" asp-action="Create" method="post">
<div class="form-group">
<label >Select Category</label>
<select class="form-control col-md-2" asp-for="CategoryId"
asp-items="#(new SelectList(Model.Categories ,"CategoryId","Name"))">
</select>
</div>
<div class="form-group">
<label>Select Branch</label>
<select class="form-control col-md-2" asp-for="BranchId"
asp-items="#(new SelectList(Model.Branches,"BranchId","Name"))">
</select>
</div>
<div >
<input type="submit" value="Save" />
</div>
</form>
Im just filling the select on the viewside and depending on what the user picks, the products I want to display. I am not passing the product list yet because I don't know where the "filter" for that particular Category takes place.
Hope you understand the idea of what i need :)
You've got two options here:
# 1 Use a Partial View And AJAX to get your data
Go have a look at the link below, it describes exactly what you want to achieve.
Populating Dropdown using partial view
# 2 Use Javascript to populate your second select:
First off you need to persist your data when the page loads
At the start of your view, add this:
#{
<text>
<script>
var data = "#Newtonsoft.Json.JsonConvert.SerializeObject(Model)";
</script>
</text>
}
Next use your on change event on the branch selector:
At the bottom of your view, do the following in the page ready event:
<script>
(function ()
{
var sltBranch = document.getElementsByName("BranchId")[0];
var sltCat = document.getElementsByName("CategoryId")[0]
sltCat.onchange = function () {
var dataAsObj = JSON.parse(data);
var branches = "";
for (i = 0; i < dataAsObj.Branches.length; i++)
{
if (dataAsObj.Branches[i].CategoryId == sltCat.value)
{
branches += "<option value='" + dataAsObj.Branches[i].BranchId + "'>" + dataAsObj.Branches[i].BranchName + "</option>"; //Whatever The branch name may be
}
}
sltBranch.innerHTML = branches;
}
}
)(document, window);
</script>
I would however advise you to follow option 1 as it is a lot more future proof strategy. This would mean that you need to change your view model etc, but if you plan on making extensive use of this strategy you need to make it more robust with something like option 1.
Good luck anyhow - happy coding.

Appcelerator Titanium dynamically populate optionDialog

I'm new to Titanium so maybe my question is a newbie one, but I'm trying to dynamically populate an option Dialog (use Alloy framework).
Is it possible to create a new ArrayCollection and pass it to my optionDialog like this :
<OptionDialog id="dialog" title="Choose Calendar" src=getAllCalendars>
<Options>
<Option id="{calendar_id}">{calendar_name}</Option>
</Options>
</OptionDialog>
Where getAllCalendar is a function that return a new Array Collection.
I know I've done things like this before in Flex but I can't make it work on Titanium so maybe it isn't the right way.
Thank you for your answers.
You need to write code in js file in Appcelerator(Alloy).
For that way you can easily get that click events.
var dialog = Ti.UI.createOptionDialog({
options : options,//Array
title : 'Hi <?'
});
dialog.show();
dialog.addEventListener('click', function(_d) {
onclickactions[_d.index];
});
I came up with this. If you opt to just create the dialog box, which works in alloy using the classic method, you can do this.
For me, the key part was to keep the order of the options with my options array. After the option was selected, you could then reference the options array with the e.index to find which was selected.
function companyDialog(){
// Build the list of options, maintaining the position of the options.
if(Alloy.Globals.Form){
Alloy.Globals.Form.Controller.destroy();
}
// My list of companies returns companyname, companycode, id
companies = db.listCompanies();
var options = [];
_.each(companies, function(val){
options.push(val.companyname + " (" + val.companycode + ")");
});
options.push("Cancel");
var dialog = Ti.UI.createOptionDialog({
title : 'Companies',
options : options
});
dialog.addEventListener('click', function(e) {
var setCode = "";
var selection = "Unknown";
if(options[e.index] != "Cancel") {
// DO WORK HERE.
alert(options[e.index].companyname);
}
});
dialog.show();
}

Multiple radio button groups in MVC 4 Razor

I need to have multiple radio button groups in my form like this:
I know it's simply done by specifying the same "name" html attribute for each group.
HOWEVER
MVC doesn't let you specify your own name attribute when using html helper like this:
#Html.RadioButtonFor(i => item.id, item.SelectedID, new { Name = item.OptServiceCatId })
Because it looks at each tag's "name" attribute (not "id") to map/bind the form to the model which the controller receives, etc.
Some said that specifying each with the same "GroupName" attribute will solve the problem, but it didn't work either.
So, is there any way which works ?
EDIT:
Here's my view (simplified):
#model Service_Provider.ViewModels.SelectOptServicesForSubServiceViewModel
#foreach (var cat in Model.OptServices)
{
//A piece of code & html here
#foreach (var item in cat.OptItems.Where(i => i.MultiSelect == false))
{
#Html.RadioButtonFor(i => item.id, item.SelectedID, new { GroupName = item.OptServiceCatId })
<br />
}
}
NOTE:
My model is a List<OptServices>:
public List<OptServices> Cats {get; set;}
And OptServices has a List of OptItems inside:
public class OptServices
{
//a few things
public List<OptItems> Items {get; set;}
}
all you need is to tie the group to a different item in your model
#Html.RadioButtonFor(x => x.Field1, "Milk")
#Html.RadioButtonFor(x => x.Field1, "Butter")
#Html.RadioButtonFor(x => x.Field2, "Water")
#Html.RadioButtonFor(x => x.Field2, "Beer")
Ok here's how I fixed this
My model is a list of categories. Each category contains a list of its subcategories.
with this in mind, every time in the foreach loop, each RadioButton will have its category's ID (which is unique) as its name attribue.
And I also used Html.RadioButton instead of Html.RadioButtonFor.
Here's the final 'working' pseudo-code:
#foreach (var cat in Model.Categories)
{
//A piece of code & html here
#foreach (var item in cat.SubCategories)
{
#Html.RadioButton(item.CategoryID.ToString(), item.ID)
}
}
The result is:
<input name="127" type="radio" value="110">
Please note that I HAVE NOT put all these radio button groups inside a form. And I don't know if this solution will still work properly in a form.
Thanks to all of the people who helped me solve this ;)
I fixed a similar issue building a RadioButtonFor with pairs of text/value from a SelectList. I used a ViewBag to send the SelectList to the View, but you can use data from model too. My web application is a Blog and I have to build a RadioButton with some types of articles when he is writing a new post.
The code below was simplyfied.
List<SelectListItem> items = new List<SelectListItem>();
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("Texto", "1");
dictionary.Add("Foto", "2");
dictionary.Add("VĂ­deo", "3");
foreach (KeyValuePair<string, string> pair in objBLL.GetTiposPost())
{
items.Add(new SelectListItem() { Text = pair.Key, Value = pair.Value, Selected = false });
}
ViewBag.TiposPost = new SelectList(items, "Value", "Text");
In the View, I used a foreach to build a radiobutton.
<div class="form-group">
<div class="col-sm-10">
#foreach (var item in (SelectList)ViewBag.TiposPost)
{
#Html.RadioButtonFor(model => model.IDTipoPost, item.Value, false)
<label class="control-label">#item.Text</label>
}
</div>
</div>
Notice that I used RadioButtonFor in order to catch the option value selected by user, in the Controler, after submit the form. I also had to put the item.Text outside the RadioButtonFor in order to show the text options.
Hope it's useful!
I was able to use the name attribute that you described in your example for the loop I am working on and it worked, perhaps because I created unique ids? I'm still considering whether I should switch to an editor template instead as mentioned in the links in another answer.
#Html.RadioButtonFor(modelItem => item.Answers.AnswerYesNo, "true", new {Name = item.Description.QuestionId, id = string.Format("CBY{0}", item.Description.QuestionId), onclick = "setDescriptionVisibility(this)" }) Yes
#Html.RadioButtonFor(modelItem => item.Answers.AnswerYesNo, "false", new { Name = item.Description.QuestionId, id = string.Format("CBN{0}", item.Description.QuestionId), onclick = "setDescriptionVisibility(this)" } ) No
You can use Dictonary to map
Assume Milk,Butter,Chesse are group A (ListA)
Water,Beer,Wine are group B
Dictonary<string,List<string>>) dataMap;
dataMap.add("A",ListA);
dataMap.add("B",ListB);
At View , you can foreach Keys in dataMap and process your action