MVC 5 Layout page - asp.net-mvc

I have an MVC site, and I use the same "_layout page" for all the view.
In _layout page, I have a select control.
What I want is to read the selected value of the control from the other pages.
Can you help me understand how to do?
Edit:
_Layout.cshtml
<div class="col-sm-4 col-xs-6">
<label class="col-sm-2 control-label" for="slt_Aziende">Azienda:</label>
<select id="mySharedSelectControl">
<option value="1">value 1</option>
<option value="2">value 2</option>
</select>
</div>
Index.cshtlm (using _Layout.cshtml)
#model IEnumerable<MySite.Models.MyModel>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
MyModelController
public class MyModelController : Controller
{
public ActionResult Index()
{
//get value from mySharedSelectControl from Layout page
var selectedValueFromLayoutPage;
//do something
return View();
}
}

Based on what #Mairaj said is right i.e you can't directly read values of controls in your controller.
What you can do is create a JavaScript function like this:
$(document).ready(function () {
$("#mySharedSelectControl").change(function () {
var dropdownValue = $(this).val();
$.ajax({
url: "#Url.Action("PutValueinSession", "MyModel")", //Action method on which you want to send this dropdown value
data: { id: dropdownValue },
success: function (e) {
window.location = window.location;
}
});
});
});
You can create a method in which you can put this value in session and used across your whole page like below:
public JsonResult PutValueinSession(int id)
{
Session["DropdownControlValue"] = id;
return Json(new { Result = "" }, JsonRequestBehavior.AllowGet);
}
Now you can access this value on any page:
public ActionResult Index()
{
//get value from mySharedSelectControl from Layout page
var selectedValueFromLayoutPage=Session["DropdownControlValue"];
//do something
return View();
}

You can't directly read value of controls in Controller, you need to send the value of dropdown to the controller and than process what you want.
Or you can directly read value of dropdown from JavaScript in other views and do your processing.

Related

Couldn't Load the data on Dropdown menu using Asp.net Mvc Json

i am creating a simple inventory control system using Asp.net Mvc Json.when i am tring to load the category data.category Data is not loaded to the Dropdown menu. code which i tried so far i attached below along with the screen shot image.
enter image description here
Form design
<div class="card-action">
<div class="form-group">
<label class="form-label">Category</label>
<select class="form-control" id="category" name="category"
placeholder="Category" required>
<option value="">Please Select</option>
</select>
</div>
</div>
Jquery
getCategory();
function getCategory() {
$.ajax({
type: 'GET',
url: '/product/Getcategory',
dataType: 'JSON',
success: function (data) {
console.log(data);
for (var i = 0; i < data.length; i++) {
$('#category').append($("<option/>", {
value: data[i].id,
text: data[i].cat_name,
}));
}
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
}
Controller
public class ProductController : Controller
{
aspoEntities db = new aspoEntities();
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Getcategory()
{
using (aspoEntities db = new aspoEntities())
{
var category = db.categories.ToList();
return Json(new { data = category }, JsonRequestBehavior.AllowGet);
}
}
}
Change your controller to
public class ProductController : Controller
{
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Getcategory()
{
aspoEntities db = new aspoEntities()
var category = db.categories.ToList();
return Json(category, JsonRequestBehavior.AllowGet);
}
}
It seems your db context has been disposed before the json is being serialized.
Try to inject the db context to your controller and get rid of the using statement.
Or move your return statement outside the using block.

pass value of a textbox from view to ActionResult using actionlink

I have a text box in view and 2 action link in the same form. what I want to do this that when I click action links textbox value will get in ActionResult
Html.BeginForm("downloadpage","Finance"){
<div class="col-5">
<input type="text" class="form-control" name="txttitle" id="txtval" placeholder="E.g. PAK10NOV18" />
#Html.TextBox("first_name")
</div>
#Html.ActionLink("Download Master File", "get_master_file");
#Html.ActionLink("Download IBFT File", "get_ibft_file");
}
backend
public ActionResult get_master_file(string txttitle)
{
return View();
}
public ActionResult get_ibft_file(string txttitle)
{
return View();
}
Why don't you use jquery and an ajax call?
Have a button that when you click calls a javascript function. In here you can get the value of the input such as this:
var textvalue = $("#txtval").val();
Create a json such as this:
var json = '{txttitle: "' + textvalue + '"}';
and call your controller such as this:
$.ajax({
url:'#Url.Action("//Function", "//Controller")',
type:'POST',
data: json,
contentType:'Application/json',
success:function(result){
//Do nothing or do whatever you want
}
});

Wrong Function Being Called From MVC View

I have an MVC view, which is launched by a function in the controller. That view has a button that I want to use to submit data to a different function in that same controller, but it always go back to the function that launched it instead.
The controller is called, the ViewForPrepare view is launched from PrepareList, I hit the button on ViewForPrepare, and it submits to PrepareList again instead of RunList.
In the controller I have:
public ActionResult PrepareList(int Key)
{
return "ViewForPrepare";
}
public ActionResult RunList(int Key)
{
return "OtherView";
}
Then in the View:
<input type="button" value="Submit Report" id="submit">
<script type="text/javascript">
$(document).ready(function () {
$('#submit').click(function () { window.location ='#Url.RouteUrl("RunList", new { Key = #Model.caseNumber })' });
});
</script>
So I press the button to go to RunList, but it keeps going to PrepareList. I've checked the routing and it looks OK. What do I need to do to get the button to submit to RunList?
You're code right now basically says "When I click the submit button. Change the window's location to something else." If that is what you want, try using
#Url.Action("RunList", new { Key = Model.caseNumber })
instead of
#Url.RouteUrl("RunList", new { Key = #Model.caseNumber })
and try using a <button> element instead of an <input> element.
If what you want is to post the data from the form, you should wrap your button in a form tag (make sure to replace "ControllerName" below with your actual controller.)
#Html.BeginForm("RunList","ControllerName", new { Key = Model.caseNumber })
{
<input type="submit" value="Submit Report" id="submit">
}
and get rid of the javascript altogether as it isn't necessary in this case. Also you will have to mark your RunList action as HttpPost for this to work.
[HttpPost]
public ActionResult RunList(int Key)
{
return "OtherView";
}
Why dont you just use a RouteLink instead of the Input?
#Html.RouteLink("Submit Report", "RunList", new { Key = Model.caseNumber }, new {#class="btn" })
not sure if you're using bootstrap or jquery ui but there are css classes to make links look like buttons.
ActionLink works the same way.
#Html.ActionLink("Submit Report", "RunList", "ViewForPrepare ", new { Key = Model.caseNumber }, new { #class = "btn" })
Using VS2015 Pro I created a project using the MVC template.
HomeController.cs added:
public ActionResult PrepareList(int Key)
{
return View();
}
public ActionResult RunList(int Key)
{
return View(); ;
}
Index.cshtml added:
#Html.ActionLink("Submit Report", "RunList", new { Key = 4 }, new { #class = "btn" })
Put a break point in "RunList" and it worked!
Using
<input type="button" value="Submit Report" id="submit">
#section script{
<script type="text/javascript">
$(document).ready(function () {
$('#submit').click(function () { window.location ='#Url.RouteUrl("RunList", new { Key = 4 })' });
});
</script>
}
I got the meessage
A route named 'RunList' could not be found in the route collection.
when you need to send data, you must add the attribute HttpPost to this action:
[HttpPost]
public ActionResult RunList(int Key)
{
return "OtherView";
}

MVC 5 partial view async postback

I have a sort of Master-Detail Edit form and I'm trying to follow this post: Using Ajax... to get the partial view to postback.
My Edit form has a partial view that has a list of sub items, and another partial create view in it to add new items. I'd like the partial create view to post back and update the list without refreshing the whole page if possible.
Here's what I have so far:
MyController.cs -
public ActionResult Edit(int? id)
{
//...
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
//...
return View(profileEdit);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomForm editForm)
{
//...
if (!ModelState.IsValid) return View(editForm);
using (var _db = new MkpContext())
{
var form = _db.CustomForms.Find(editForm.CustomFormId);
//...
_db.Entry(form).State = EntityState.Modified;
_db.SaveChanges(User.ProfileId);
return RedirectToAction("Index");
}
}
public ActionResult _CustomFieldList(int id)
{
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
var formCustomFields = (from cf in _db.CustomFields
where cf.CustomFormId == id
select cf);
return PartialView(formCustomFields.ToList());
}
}
// Nested in _CustomFieldList
public ActionResult _CustomFieldCreate(int id)
{
var newField = new CustomField
{
CustomFormId = id
};
return PartialView(newField);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _CustomFieldCreate(CustomField addField)
{
ViewBag.CustomFormId = addField.CustomFormId;
if (ModelState.IsValid)
{
using (var _db = new MkpContext())
{
_db.CustomFields.Add(addField);
_db.SaveChanges();
}
var newField = new CustomField
{
CustomFormId = addField.CustomFormId
};
return PartialView(newField); // Probably need to change this somehow
}
return PartialView(addField);
}
And the views:
Edit.cshtml -
#model PublicationSystem.Model.CustomForm
#{
ViewBag.Title = "Edit Custom Form";
Layout = "~/Views/Shared/_LayoutSmBanner.cshtml";
}
<div class="form-horizontal">
<div class="row">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#* Fields for this form *#
}
<div id="CustomFields" class="col-md-6">
#Html.Action("_CustomFieldCreate", new { id = ViewBag.CustomFormId })
</div>
</div>
</div>
<script>
$(function () {
$("#createFieldForm").on("submit", function (e) {
e.preventDefault(); //This prevent the regular form submit
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$("#CustomFields").html(result);
}
});
return false;
});
});
</script>
_CustomFieldCreate.cshtml -
#model PublicationSystem.Model.CustomField
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div id="result"></div>
<div class="form-horizontal">
<h4>CustomField</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model =>model.CustomFormId)
<div class="row">
#* Fields for the form *#
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div id="customFieldList">
#Html.Action("_CustomFieldList", new { id = ViewBag.CustomFormId })
</div>
_CustomFieldList.cshtml
#model System.Collections.Generic.IEnumerable<PublicationSystem.Model.CustomField>
<table class="table">
#* List table code *#
</table>
Edit: I rewrote the pages so that the list is part of the create partial view. What happens now is, if you enter data for _CustomFieldCreate and press submit, the first time, it refreshes just that view (including the nested list view). However the second time, it redirects to the view, probably because the first refresh didn't rebind the javascript to the submit button. Also, the Create view doesn't clear out the fields, but persists the originally entered data.
You will need a form in your partial view whose submit action binds to a javascript function that posts to your controller.
For example if your form id is MyForm:
$('#MyForm').on('submit', function (e) {
e.preventDefault(); //This prevent the regular form submit
$.ajax({
url: $(this).action, // This will submit the post to whatever action your form goes to
type: "POST", // This tells it that it is a post
data: $(this).serialize(), // This sends the data in the form to the controller
success: function (data) {
// do some javascript on success
},
error: function (xhr, ajaxOptions, thrownError) {
// do some javascript on error
}
});
});
This javascript overrides the default form submit and does an ajax post to your controller and then returns with success or error where you can do anything you want.
Here is some jquery ajax documentation:
http://api.jquery.com/jquery.ajax/
You should look into using AJAX. That should accomplish what I think you are describing. You'll want to create a javascript function that handles the submit event on the form, then post the form data to some create action in your MVC app using AJAX. If you are using jQuery, the library makes it pretty simple.
http://api.jquery.com/jquery.ajax/

how to get partialview data in controller

I am using three partialview on a single view, I have a submit button on clicking of which I want to send information to database, I have to retrieve data from all the partialview.
Can You please provide me correct information to do it.
Darin I m using L2S so when I drag my stored procedure, I get code some thing like this in
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="SP_Name")]
public int SP_Name(
[global::System.Data.Linq.Mapping.ParameterAttribute(Name="EmployeeID", DbType="Int")] System.Nullable<int> EmployeeID
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), EmployeeID);
encounterID = ((System.Nullable<int>)(result.GetParameterValue(293)));
return ((int)(result.ReturnValue));
}
}
Updated
<script language="javascript" type="text/javascript">
$(function () {
$('#Form1').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (data) {
var message = data.Result;
$('#Result').html(message);
}
});
return false;
});
});
</script>
In my Controller I am using
public ActionResult Index(FormCollection frm)
{
My Code ---------------------
return Json(new { Result = "Success" });
}
When I return this I m getting a file in post back and it ask me to save it.
I have checked using flidder, in URL it shows me that the path as / only
where as If I fill any particular partialview It shows something like /Controller Name/Partialview
Can You help me with this problem
Well, sending data to a controller action is usually done by performing an HTTP request to this controller action. There are different ways of performing an HTTP request:
Use a <form> tag pointing to this action
Use AJAX
So if you go with the first approach you could have a single <form> wrapping all the partials which would have multiple submit buttons (with different names). Then when you click on one submit buttons all the input fields will be sent to the controller action and then inside the controller action you could process the data based on which submit button was clicked.
If you use the second option, well, then simply harvest the values you need to be sent uipon button click and send them along the AJAX request.
UPDATE:
As requested in the comments section here's how the first technique could be put into action. It uses two partials instead of three but it could be easily extrapolated.
As always you start by defining a view model which will represent the data you would like to work with on this particular view:
public class MyViewModel
{
public Partial1ViewModel Model1 { get; set; }
public Partial2ViewModel Model2 { get; set; }
}
public class Partial1ViewModel
{
public string Foo { get; set; }
}
public class Partial2ViewModel
{
public string Bar { get; set; }
}
Then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Model1 = new Partial1ViewModel { Foo = "foo" },
Model2 = new Partial2ViewModel { Bar = "bar" },
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// Here you have access to model.Model1.Foo and model.Model2.Bar =>
var button = "";
if (!string.IsNullOrEmpty(Request["submit1"]))
{
// submit1 button was used
button = "submit1";
}
else if (!string.IsNullOrEmpty(Request["submit2"]))
{
// submit2 button was used
button = "submit2";
}
var result = string.Format("thanks for submitting using {0}", button);
return Content(result, "text/plain");
}
}
and then a main view (~/Views/Home/Index.cshtml):
#model MyViewModel
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.Model1)
#Html.EditorFor(x => x.Model2)
}
and the two corresponding editor templates (or partials if you will):
~/Views/Home/EditorTemplates/Partial1ViewModel.cshtml:
#model Partial1ViewModel
<h2>Partial 1</h2>
<div>
#Html.LabelFor(x => x.Foo)
#Html.EditorFor(x => x.Foo)
<input type="submit" value="Submit me!" name="submit1" />
</div>
~/Views/Home/EditorTemplates/Partial2ViewModel.cshtml:
#model Partial2ViewModel
<h2>Partial 2</h2>
<div>
#Html.LabelFor(x => x.Bar)
#Html.EditorFor(x => x.Bar)
<input type="submit" value="Submit me!" name="submit2" />
</div>

Resources