Loading partial view depending on dropdown selection in MVC - javascript

I apologize I am still fairly new to MVC. I currently have a dropdownlist with some options. What I would like to do is depending on the dropdownlist value that I select then I should be able to render a partial view. I want the partial view to load as soon as the user selects from the dropdownlist.
Also, I am able to render my partial view but it's not returning what I need. When I select from the dropdownlist it does not take the functionID..it just returns all of the items regardless of the functionID.
I want the partial view to render based off the functionID.
Thank you very much. Any help is very much appreciated it.
Main View
#Html.DropDownListFor(m => m.FunctionID, new
SelectList(Model.functionList, "FunctionID", "Name"), "Select
Function", new {#id="id"})
<div id="partialPlaceHolder">
</div>
Partial View
#foreach (var items in Model.itemTypeList)
{
<pre> #items.Definitions</pre>
}
Controller
[HttpGet]
public ActionResult ViewOverview()
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
Words viewModel = new Words();
MetricDefinitions(viewModel);
return View(viewModel);
}
[HttpGet]
public ActionResult GetWords()
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
Words viewModel = new Words()
{
itemTypeList = itemTypeList,
functionList = functionList
};
return PartialView("_ViewWords", viewModel);
}
private void MetricDefinitions(Words model)
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
model.functionList = functionList;
model.itemTypeList = itemTypeList;
}
javascript
$(document).ready(function () {
$('#id').change(function () {
var selectedID = $(this).val();
$.get('/Home/GetWords/' + selectedID, function (data) {
$('#partialPlaceHolder').html(data);
/* little fade in effect */
$('#partialPlaceHolder').fadeIn('fast');
});
});
});

I have added NetFiddle. It works here
Can you try to add selectedItem param into action and use jquery .load() function to get partial result into your target element.
[HttpGet]
public ActionResult GetWords(int selectedItem) // add your selectedVal value in controller
{
.....
}
jquery
// it is going to parse partial view into target div
$("#id").on("change", function(){
var url = '#Url.Action("GetWords", "Home")' + "?selectedItem=" + $(this).val();
$("#partialPlaceHolder").load(url, function(){
console.log("It worked");
$('#partialPlaceHolder').fadeIn('fast');
})
})

Related

MVC MultiSelectList or Input loop only returns first value to controller

I have a controller that uses a ViewBag to bring the data into the view.
var _021CheckBox = dc.OptionsTbls.Where(a => a.Question_ID == 21).ToList();
ViewBag.CheckBoxfacilities = new SelectList(_021CheckBox, "ID", "QOption").ToList();
Then i have the View that's supposed to submit a string back to the controller but it only sends the first selected item. I even tried Javascript to combine the two but that did not work either. here's my view (both listboxfor and loop
//Loop
#for (int i = 0; i < ViewBag.CheckBoxfacilities.Count; i++)
{
#Html.HiddenFor(model => model._021CheckBox[i], new { #id = "_021CheckBox" })
<input name="_021CheckBox" type="checkbox" value="#ViewBag.CheckBoxfacilities[i].Text" id="#ViewBag.CheckBoxfacilities[i].Value" /> #ViewBag.CheckBoxfacilities[i].Text <br />
}
// listboxfor
#Html.ListBoxFor(m => m._021CheckBox, new MultiSelectList(ViewBag.CheckBoxfacilities, "Value", "Text"), new { #Multiple = "multiple" })
//JavaScript that appends the value
<script>
var Values = [];
$('input[name=_021CheckBox]').change(function () {
if (this.checked) {
Values.push($(this).val() + ";");
}
else {
Values.pop(this);
}
$('#_021CheckBox').val(Values).appendTo('form');
document.getElementById("_021CheckBox").value = Values;
});
</script>
here is my Model. I think maybe this is where i'm messing up
[Table("TBLMajorQuestions")]
public partial class TBLMajorQuestion
{
[Key]
public int ID { get; set; }
public string _021CheckBox { get; set; }
}
I think i was trying to fit a square peg into a circle. The easiest thing to do is editvmy column from _021CheckBox to _021aCheckBox and to add two more columns into my table. _021bCheckBox and _021cCheckBox. Now i change them from strings to bits and update my model accordingly.
In the view, i took out all the extra javascript and did #html.CheckBoxFor(m => m._021aCheckBox). Done! Did the same for the other two checkboxes.

Loading selected GridView Item in Popup using CallBacks with ASP.Net MVC

I still relatively new to ASP.Net and the concepts of communicating between client and server. I am using DevExpress tools but I believe this issue is more of a misunderstanding of the concept.
I have a GridView within a partial view that is loaded via an Action #Html.Action('MessageGridView'). This works no problem and data is loaded fine with the index and a returned model.
#Html.DevExpress().GridView(settings =>
{
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.Name = "preparedMessagesGrid";
settings.CallbackRouteValues = new { Controller = "Messages", Action = "MessagesGridView" };
settings.KeyFieldName = "Id";
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.Init = "GridViewInit";
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
settings.ClientSideEvents.BeginCallback = "OnBeginCallback";
settings.SettingsBehavior.AllowEllipsisInText = true;
settings.PreRender = settings.Init = (sender, e) =>
{
MVCxGridView gridView = sender as MVCxGridView;
gridView.Selection.SelectAll();
};
settings.Columns.Add("Name");
settings.Columns.Add("Description");
}).Bind(Model.preparedMessages).GetHtml()
What I am trying to achieve is when the user selects the row I wish the data to be loaded into the popup control when clicked. Is there a way I can set the parameters dynamically for the popup control callback?
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
settings.Width = 100;
settings.AllowDragging = true;
settings.CloseAction = CloseAction.CloseButton;
settings.CloseOnEscape = true;
settings.PopupAnimationType = AnimationType.None;
settings.HeaderText = "Login";
settings.Modal = true;
settings.PopupHorizontalAlign = PopupHorizontalAlign.WindowCenter;
settings.PopupVerticalAlign = PopupVerticalAlign.WindowCenter;
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load", new { id = THIS NEEDS TO BE SELECTED ID VALUE} };
settings.LoadContentViaCallback = LoadContentViaCallback.OnFirstShow;
}).GetHtml()
It works if I set the value static so I'm one step away from getting this working. What I have researched is that I can get the values from the GridView in javascript using the selection changed event.
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues("Id", GetSelectedFieldValueCallback);
}
I can then retrieve this value but can I set this to my popup control or am I misunderstanding being relatively new and possibly I could do this server side for when the ViewGrid callback is performed, then set it server side with a session of some sort?
You're just one step away to get currently selected grid value with this function:
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
What you need to do is declaring GetSelectedFieldValueCallback method as this (I got from a test that selectedValue contains array with single value for single grid row selection, use zero index to assign the value):
var id; // a global variable set to hold selected row key value from grid
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
Then setting BeginCallback on PopupControl helper as given below, note that for DevExpress HTML helpers you can use customArgs in client-side to pass action method parameters instead of using CallbackRouteValues with id parameter:
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
// JS function for popup callback
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id; // this sends 'id' as action method parameter to `Load` action
}
// Optional end callback
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
Finally, let's putting them all together in view & controller code:
View
<!-- View page -->
<script type="text/javascript">
var id;
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id;
}
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
</script>
GridView (partial view)
#Html.DevExpress().GridView(settings =>
{
settings.Name = "preparedMessagesGrid";
// other stuff
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
}).Bind(Model.preparedMessages).GetHtml()
Popup (partial view)
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
Controller
public class Messages : Controller
{
public ActionResult MessagesGridView()
{
// grid view populating data code lines here
return PartialView("_GridView", data);
}
public ActionResult Load(int id)
{
// code lines to find ID here
return PartialView("_ModalPopup", model);
}
}
References:
(1) Display GridView Row Details in PopupControl Window
(2) How to display detail data within a popup window (MVC)
(3) ASPxClientGridView.GetSelectedFieldValues (DevExpress Documentation)
(4) MVCxClientBeginCallbackEventArgs.customArgs (DevExpress Documentation)

ASP.NET MVC -Refresh CodeMirror editor onclick

I have a codemirror editor in a partial view and a list of files in the main view. I want to refresh the editor once a file name is clicked. I tried many solutions provided on StackOverflow and other websites but nothing worked , and This is my first time using Javascript so I can't figure out What am I doing wrong.
This is my code:
Controller:
public ActionResult Index()
{
StudentsCodes model = new StudentsCodes();
model.Student = (Student)CurrentUser;
var user = UserManager.FindById(((Student)CurrentUser).InstructorID);
model.Instructor =(Instructor) user;
return View(model);
}
public PartialViewResult DevelopmentPartial (StudentsCodes path )
{
return PartialView(path);
}
Main view:
<script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script type="text/javascript" src="~/Scripts/jquery-3.1.1.js"></script>
<ul id="tree">
#foreach (var file in Directory.GetFiles(Server.MapPath("~/Content/" + Model.Student.UserName + "/CompilerProject/" + name)))
{
var filename = Path.GetFileName(file);
<li id="filelist" onclick="#(Model.path = "~/Content/" + Model.Student.UserName + "/CompilerProject/src/" + #filename)">
<span class="glyphicon glyphicon-file"></span>
#filename
/li>
}
<div id="partial">
#{
Html.RenderPartial("DevelopmentPartial",null);
}
</div>
<script>
$(document).ready(function () {
$("#filelist").click(function (e) {
#{Html.RenderAction("DevelopmentPartial", Model);
}
});
});
</script>
partial view:
#using (Html.BeginForm())
{
var fileContents= "";
if (Model==null)
{
fileContents = "";
}
else
{
fileContents = System.IO.File.ReadAllText(Server.MapPath(Model.path));
}
#Html.TextArea("code", fileContents, new { id = "code" })
}
I can't assign ids for list elements since their number is unknown at compile time and it changes when the user adds or deletes a file, that's why most of the solutions provided didn't work . The result here was 3 editors overlapping and display the contents of the last file. And <li> items are non-clickable. What am I doing wrong in my code ?
Edit:
After updating the script as the following:
<script>
$(document).ready(function() {
$(".filelist").on("click",function (e) {
$("#partial").load('DevelopmentPartial');
});
});
</script>
It refreshes the partial view but the editor is always empty, and the Model is always null. Is it wrong to update the Model using "onclick"?
In case someone faced the same problem, I solved it by changing id to class at the list, then by using this script:
<div id="partial">
#{
Html.RenderAction("DevelopmentPartial", new { path1 = Model.path});
}
</div>
<script>
$(document).ready(function () {
$('.filelist').on('click', function (e) {
alert('Im clicked on filePath = ' + $(this).attr('value'));
var filePath = $(this).attr('value'); //value is attribute set in Html
$('#partial').load('DevelopmentPartial', { path1: filePath });
});
});
</script>
And the controller:
public PartialViewResult DevelopmentPartial(string path1)
{
modelSC.path = path1;
return PartialView(modelSC);
}
where modelSC is a global variable in the controller.

jquery dialog popup shown in the same window

I dont know whats wrong.
I follow this link http://www.dotnetcodesg.com/Article/UploadFile/2/286/CRUD%20operation%20using%20Modal%20Popup%20in%20ASP.NET%20MVC%204.aspx because need pretty same thing: CRUD grid with popup for edit.
I do everything inside HomeController and Index.cshtml which generated by VS2013.
I cut from the code the things involved:
Index.cshtml
grid.Column("", header: "Actions",
format: #<text>
#Html.ActionLink("Edit", "EditConstruct", new { id = item.Id, #class = "editDialog" })
<div id="dialog-edit" style="display: none">
Controller
public ActionResult EditConstruct(int id)
{
var data = advConstructRepository.Get(id);
AdvConstructModel model = new AdvConstructModel
{
Id = data.Id,
Description = data.Description,
MaintenanceTime = data.MaintenanceTime,
Location = data.Location,
Height = data.Height,
Width = data.Width,
MonthlyCost = data.MonthlyCost,
AdvConstructType = advConstructRepository.GetAdvConstructType(data.AdvTypeId)
};
ViewBag.IsUpdate = true;
return View("EditConstruct", model);
}
Edit View
#model AdvApplication.Models.AdvConstructModel
#{
Layout = null;
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm("UpdateConstruct", "Home", "POST"))
{
#Html.ValidationSummary(true)
ViewBag.IsUpdate = true;
return View("EditConstruct", model);
}
etc...
But when i clicked on Edit action, i receive fields for edit but not in the popup, but on whole screen as a single page.
EditConstruct view was created as partial view.
Please suggest how to fix
It is probably the whole view being sent back, jquery deals in fragments, not whole pages.
Consider this change:
public ActionResult EditConstruct(int id)
{
var data = advConstructRepository.Get(id);
AdvConstructModel model = new AdvConstructModel
{
Id = data.Id,
Description = data.Description,
MaintenanceTime = data.MaintenanceTime,
Location = data.Location,
Height = data.Height,
Width = data.Width,
MonthlyCost = data.MonthlyCost,
AdvConstructType = advConstructRepository.GetAdvConstructType(data.AdvTypeId)
};
ViewBag.IsUpdate = true;
if(Request.IsAjaxRequest())
return PartialView("EditConstruct", model);
return View("EditConstruct", model);
}

Not able to pass the values from MVC(Razor) view to JsonResult method in Controller

I'm having two dropdown lists in my MVC(Razor) view: Country and State.
I'm able to fill both the dropdown's independent of each other.Now i want to fill second dropdown(State) based on the change event of Country's dropdown.
For this I have used JsonResult method in Controller and for this method i'm passing countryID on the Change event of Country from my view inorder to fill my second dropdown state.
Problem Statement: The JsonResult method is getting triggered from my view but the CountryId value is not getting passed from view to controller in-order to fill state.
What i'm doing wrong here?
View:
Javascript:
<script type="text/JavaScript">
function CountryChange() {
var url = '#Url.Content("~/MasterConfigGeneral/GetState")';
var ddlsource = "#CountryID";
var ddltarget = "#StateID";
if ($(ddlsource).val() != "") {
$.ajaxSetup({ cache: false });
$.getJSON(url, { countryID: $(ddlsource).val() }, function (data) {
$(ddltarget).empty();
$("#StateID").append("<option value=''>Select State</option>");
$.each(data, function (index, optionData) {
$("#StateID").append("<option value='" + optionData.Value + "'>" + optionData.Text + "</option>");
});
});
}
else {
$("#StateID").empty();
$("#StateID").append("<option value=''>Select State</option>");
}
}
</script>
Dropdown's in my View:
<div class="cssclass">
#Html.DropDownListFor(model => model.companyModel.CountryID, new SelectList(Model.ddlCountryStateCity.ddlCountry, "Value", "Text"), "Select Country", new { onchange="CountryChange()" })
#Html.ValidationMessageFor(model => model.companyModel.CountryID)
</div>
<div class="cssclass">
#Html.LabelFor(model => model.companyModel.StateID)
</div>
<div class="editor-field">
#Html.DropDownList("stateid",Model.ddlCountryStateCity.ddlState,"Select State")
#Html.ValidationMessageFor(model => model.companyModel.StateID)
</div>
Controller:
Country Dropdown:
#region Country
public DropdownListCountryStateCity FillDropDownListCountry()
{
objDropDownCountryStateCity.ddlCountry = (from s in dbEntity.Countries
select new SelectListItem()
{
Text = s.Name,
Value = s.CountryID
}).ToList<SelectListItem>();
return objDropDownCountryStateCity;
}
#endregion
State Dropdown:
#region State
public JsonResult GetState(string countryID)
{
JsonResult jsResult = new JsonResult();
objDropDownCountryStateCity.ddlState = (from csc in dbEntity.CountryStateCities
join c in dbEntity.Countries on csc.CountryID equals c.CountryID
join s in dbEntity.States on csc.StateID equals s.StateID
where csc.CountryID == countryID
select new SelectListItem()
{
Text = s.Name,
Value = s.StateID
}).ToList<SelectListItem>();
jsResult.Data = objDropDownCountryStateCity.ddlState;
jsResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsResult;
}
#endregion
Your problem lies on how the DropDownListFor helper generates the element.
In your code, it's generating names and ids something like this:
<select id="companyModel_CountryID" name="companyModel.CountryID">
...
</select>
In your javascript the ddlSouce is "#CountryID". Since there's no element with that id, jQuery pass null as data to $.getJSON. That's why the controller method receives nothing.
You have two options:
Change ddlSource javascript to the proper id (you'll have to see on the source code) OR
Change the last DropDownListFor helper from
new { onchange="CountryChange()" }
to
new { id = "CountryID", onchange="CountryChange()" }
IMHO, the last option is the best choice.

Categories

Resources