I have a Hidden field in a Partial View
#Html.HiddenFor(model => model.Type, new { id = "Type" })
In my JS for the page in document.ready function I am trying to get the value for this Field using:
var type = $('#Type').val();
alert(type);
The value Type is set in two partial views which then Render the other Partial View as below:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
{ Model.Type = TypeEnum.Diesel; }
<p>
#{ Html.RenderPartial("_MyOtherView"); }
</p>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
{ Model.Type = TypeEnum.Petrol; }
<p>
#{ Html.RenderPartial("_MyOtherView"); }
</p>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
{ Model.Type = TypeEnum.Electric; }
<p>
#{ Html.RenderPartial("_MyOtherView"); }
</p>
}
However when I naviagte between the Tabs which load the content the alert only ever fires with the 'Diesel' value - I change the HiddenFors to TextBoxFor and on screen I can see the contents of the textbox gets updated to Diesel/Petrol/Electric on moving between Tabs but I cannot figure out why the alert is not getting changed?
Unless you used "Type" as an example ID, you seem to be rendering three partial views, each containing a hidden input with ID "Type". The result is a page with three inputs with the same ID, causing a conflict if you're trying to get their value the way you did in your script.
I suggest putting classes on them, for example "hiddenInput", and then updating your script to something similar to this:
$('.hiddenInput').each(function() {
alert($(this).val();
});
Related
I have an MVC 5 Application. I have a View that inherits from a Model View. I have a DropDownlistFor with Validation that cannot be empty.
The problem I have is that Validation executes as soon as I select an item from Dropdownlist. When I select the same First item "Choose a Country", I mean, y select the same default option, validation execute and show a Message "Country is required"...
I put an alert on jquery Submit button and on Controller Method and it does not reach that point.
Another curious thing is that this App is a Migration from Entity Framework to Enterprise Library Store Procedure ..
The Model that inherits the View is loaded on the Controller from Store Procedure instead of EntityFrawork.
This should be transparent to the View. But this error happens only in this versión. It Works fine with Entity Framework.
Here is part of the code..
#model AvivaVozSP.Models.UserViewModel
#using System.Web.Mvc.Ajax
<form action="#Url.Action("Create", "Users")" id="form" enctype="multipart/form-data" method="post">
<div class="DvCampoUp">
#Html.DropDownListFor(m => m.user.Country_id, Model.AvailableCountries, new { #class = "StyleOb Required txtFill", #onclick = "ocultar();", #onchange = "javascript:GetState(this.value);", #id = "Country_id" })
</div>
<div class="DvCampoUp">
#Html.ValidationMessageFor(model => model.user.Country_id, "", new { #class = "text-danger" })
</div>
</form>
<script language="javascript" type="text/javascript">
$('form').submit(function (event) {
alert(1);
});
Any Ideas?
Use the default value like this
<div class="DvCampoUp">
#Html.DropDownListFor(m => m.user.Country_id, Model.AvailableCountries,"Choose a Country", new { #class = "StyleOb Required txtFill", #onclick = "ocultar();", #onchange = "javascript:GetState(this.value);", #id = "Country_id" })
</div>
and remove Choose a Country from the list
I am using partial view to display a view inside another and the partial view has the drodown so how to get the value of that dropdown actually i want to display another dropdown based on the value of the first dropdown here is my code in detail:
partial view:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<link href="~/Content/control.css" rel="stylesheet" />
<fieldset>
<legend></legend>
<div class="editor-label">
#Html.LabelFor(model => model.CompanyID , new {#class="lbldis"})
</div>
<div class="editor-field">
#Html.DropDownListFor(Model => Model.CompanyID, new SelectList(ViewBag.CompanyList as System.Collections.IEnumerable, "_CompanyID", "Company"), "- Select -",new { #class = "txtbox",id="ddln" })
#Html.ValidationMessageFor(model => model.CompanyID)
</div>
<br />
<div>
#Html.DropDownListFor(Model => Model.ClientID, new SelectList(ViewBag.ClientList as System.Collections.IEnumerable, "_ClientID", "Company"), "- Select -",new { #class = "txtbox" })
#Html.ValidationMessageFor(model => model.ClientID)
</div>
</fieldset>
}
and the view where i am calling this partial view:and the name of that view is Index:
<div id="tab-1">
#Html.Partial("~/Views/PartialViews/_company.cshtml")
</div>
All the dropdowns are working fine and getting the values and all but only problem is with the javascript. Please help me on where to write the javascript i.e in partial view or in Index where I am calling my partial view and how to to display another dropdown based on the value of the first one.
What I have tried so far is below:
<script type="text/javascript">
$("#ddln").change(function onchange(dropdown) {
var myindex = dropdown.selectedIndex;
var SelValue = dropdown.options[myindex].value;
if (SelValue == 'Client3')
{
var see = document.getElementById("ddln");
see.style.display = "";
}
})
</script>
If you are using jquery you can handle controls of partial view from main view using on() function. Earlier (before 1.9) you could have used live() but this has been deprecated since.
$(document).ready(function () {
$('body').on("change", "#ddln", function (evt) {
if ($(this).val() != 'val1') //assume if val1 is the value against which we wish to show.
{
$('#ndl').show();
}
else
{
$('#ndl').hide();
}
});
});
To hide or display the 2nd dropdown based on a value in the first:
var clients = $('#ClientID');
$('#CompanyID').change(function() {
var id = $(this).val();
if (id == 'Client3') { // assume you want to hide it if the selected option value is 'Client3'
clients.hide();
} else {
clients.show();
}
});
Edit
Based on OP's last edit which changed the default id attribute from id="Company" to id="ddln", the code would be modified to
$('#ddln').change(function() { ...
I am using a standard MVC4 EF5 setup and have a standard view which loads data from the db onto a table.
At the start of the table I have a column for each record with an Add button. The functionality I want is to click the button, popup a model dialog box with a form and add something to the item in the grid that was clicked (a 1 to many).
Lets say I have a list of vans available shown in the list. And when I click the add button beside the particular van where I want to add a passenger, I want a popup to show that allows me to type the details of the passenger so they can be assigned to that van.
I think I am over complicating this. But my brain is fried. I tried partial views with ajax. I tried jQuery UI.Dialog. Im just lost. I am trying to figure out how to find the id of the record I clicked (given the buttons are all generated by a for each loop in the view as normal and numbering them 1 to X does not tell me the id of the record I clicked). So even if I get the popup showing, I wont know which van to assign the passenger to.
If your woundering where the passenger list is coming from, its another table. And effectively any passenger can be assigned to any van. Its hypothetical.
Im actually working on a document generator and so there is a many to many relationship between document parts and documents (a given document part, can appear or belong to many documents, and a document can contain many document parts). I know its messy, this is why I did not want to use the real example.
I'm thinking its maybe an easy enough problem to solve but I have been at it since Friday and the brain left home!
Edit: Adding Code:
Here is the main view: The main problem I am having with this is the way the grid is constructed. I think its partially razor, partially html, partially html helper, and partially javascript. I don't know which part is which, but I just need to get a popup to show for each button in the table, and to have an id I can assign values to. I cant figure out how to do it here.
Html.Grid(dbaccess().Where(c => something = something
).Select(o => new
{
Name = o.Name,
Comment = o.Comment,
Status = o.Status,
}
, "grdConfiguration", 0, htmlRowClass: (p) => (row++ % 2 != 0) ? "" : "oddRow"
, columns: new[]{
//THIS IS THE PROBLEM LINE BELOW .... It shows a button in the table, but...
//how do I make it unique. Is it even necessary to do so.
// How do I get the ID of the record at this location when this button is pressed.
//This is the code as originally posted: For context
new Helpers.GridColumn(value: (a) => "<input type=\"button\" class=\"btn\" id=\"BtnHello\" value=\"Add\" />"),
//for some reason when I try the following alternative as suggest by the answers so far - it doesn't work.
new Helpers.GridColumn(value: (a) => "<input type=\"button\" class=\"btn\" data-ThisId=\"#model.SomeId\" value=\"Add\" />"),
//THIS IS THE PROBLEM LINE ABOVE....
there is more columns but this button calls the jQuery...
On this view I also have some Div tags in which to load the partial... I can actually get this to popup. But that's about all I can do. And only when I click the first button in the table.
<div id='SomePopUp' style='display: none;'>
//#using (Html.BeginForm())
//{
// <div>
// <span class="display-label">Quantity: </span>
// <span class="display-field"><input type="text" id="txtQuantity" /></span>
// </div>
// <div>
// <span class="display-label">Comments: </span>
// <span class="display-field"><textarea rows="7"></textarea></span>
// </div>
//}
</div>
I also have a script section on this view with the code for the popup:
<script type="text/javascript">
$("#BtnHello").click(function ()
{
$("#SomePopUp").dialog(
{
resizable: false,
height: 400,
width: 400,
modal: true,
title:"add to {Some ID}:", //I want the id to show here so I know I have the record I want.
buttons:
{
Submit : function ()
{
$(this).dialog('Some Text');
},
Cancel: function ()
{
$(this).dialog('close');
}
}
});
});
</script>
I have a controller:
[HttpGet]
public ActionResult AddExtra(int id)
{
//Fairly sure I should be doing something with this id, but how do I get it from the button.
return PartialView();
}
And for the partial view I have
#model CM.ViewModels.AddExtraPackagesViewModel
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Add Something</h3>
</div>
<div>
//I was using ajax here...
#*#using (Ajax.BeginForm("DoSomething", "Something", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-something"
}))
{
<div class="modal-body">
#Html.TextBoxFor(x => x.Quantity);
#Html.TextAreaFor(x => x.Comment);
</div>
<div class="modal-footer">
<button class="btn btn-success" id="submit">Save</button>
Close
</div>
}
</div>
I made a little view model too but...
public class AddExtraViewModel
{
public int Id { get; set; }
public string Quantity { get; set; }
public string Comment { get; set; }
}
I apologise if this is all over the place but I did not write the original code. There were about 7 other programmers here before me and I'm just struggling to get through it.
Any help would be appreciated.
I think you would want something like this (using jQuery and jQuery UI):
Controller:
public ActionResult SomeAction(int id) {
return View(new YourModel { Id = id });
}
Partial View:
#model YourProject.Models.YourModel
// Partial view content e.g. the form etc.
Your view:
/<!-- html etc. -->
<table>
<tr>
<td>Add</td>
</tr>
</table>
<script>
$(function(){
$(".add-button").click(function(){
var options = {
autoOpen: false
}
var dialog = $("<div>").dialog(options);
var id = $(this).data("theId");
dialog.load("the/url/to/the/controller/action", { id: id }, function(){
dialog.dialog("open");
dialog.find("form").submit(function(){
// do stuff
dialog.remove();
return false;
});
});
});
});
</script>
if you are building buttons in a forloop you don't want to define an id on the button. Duplicate id's on a view can cause lots of issues. Use a class on the buttons instead to trigger off of and use $(this) in your script to get details of the button that was clicked. To access buttons on a partial or on items that are added to your page after page load you need to tie the click event for that button to the document like this
$(document).on("click", ".btnDetails", function(){
//your script here
});
The other example uses "this" and shows how you can pass the id of the clicked button back to the controller. The controller will need to be a little different though
public PartialViewResult PopulatePartial(int ID){
var Model = //populate your model based on the passed id
return PartialView("PartialViewName", Model);
}
Problem Statement: I want to change the display name of labels(#Html.LabelFor) in Razor view of MVC based on the display names which i get from db.
I have added the dropdown list of languages in the _Layout.cshtml
<li>#Html.Action("Index", "LanguageDropdown", new { languageid = Request["languageId"] })</li>
I have created one partial view for drop down:
#model ALCMS.Web.Models.Master_or_Configuration.LanguageDropdownModel
<script type="text/javascript">
function GetLanguage() {
var languageId = $('#LanguageId').val();
var Url = "#Url.Content("~/MasterConfigGeneral/GetLanguage")";
$.ajax({
url: Url,
dataType: 'json',
data: { LanguageId: languageId },
success: function (data) {
}
});
}
</script>
<div style="display:inline-block">
#Html.DropDownListFor(l => l.LanguageID, new SelectList(Model.Languages, "Value", "Text"), "Select Language", new { id = "LanguageId" ,onchange="GetLanguage()" })
</div>
Partial View Controller:
public ActionResult Index(string languageId)
{
//return View();
var languages = dbEntity.LookupLanguages;
var model = new LanguageDropdownModel
{
LanguageID = languageId,
Languages = languages.ToList().Select(l => new SelectListItem
{
Value = Convert.ToString(l.LanguageID),
Text = l.Name
})
};
return PartialView(model);
}
In Controller Json Result method:
public JsonResult GetLanguage(int languageID)
{
JsonResult jsResult = new JsonResult();
objdbGlobalTenant.ddlLanguage = (from lsr in dbEntity.LocaleStringResources
where lsr.LanguageID == languageID
select new SelectListItem()
{
Text = lsr.ResourceValue,
Value = lsr.ResourceName
}).Distinct().ToList<SelectListItem>();
//ViewBag.Language = objdbGlobalTenant.ddlLanguage;
jsResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsResult;
}
Now everything is working fine.I'm able to get the selected langaugeID in Json Result method in Controller based on the change event of Language dropdown. Based on this Language ID i'm getting display names(ResourceValue) which i need to apply for the particular view.
Problems:
1>After getting the display names from db how to change display names
of particular view when language change event triggers.?? For
ex:Currently i'm seeing the Create.CSHTML. Now if i change the
language dropdown it should trigger Json Event in controller and
after getting values it should apply the values on the view which it
got from db.
Note: Dropdown is in Layout.cshtml(like master in .aspx)
2>Drop-down which i placed in Layout.cshtml is getting refreshed
every time new view is loaded which inherits(layout.cshtml).How to
make the controller to retain it's state during postback??
3>How to get the selected drop-down item from the layout in multiple
Controllers,to change the display name in each view based on the langaugeid
of dropdown in layout
How to do this??If i'm doing wrong suggest me some other ways...
Below are the suggestions :
Issue 1 :
You may keep one attribute in each label which identifies them uniquely.
Your HTML should render like following
<!-- For English -->
<label label-unique-name="Name">Name</label>
<label label-unique-name="Surname">Surname</label>
<!-- For French -->
<label label-unique-name="Name">nom</label>
<label label-unique-name="Surname">nom de famille</label>
<!-- For Spanish -->
<label label-unique-name="Name">nombre</label>
<label label-unique-name="Surname">apellido</label>
Here label-unique-name is your attribute, which will remain fixed for each language. Now when you change the language from dropdown you will bring the values like below.
<!-- For English -->
<label-unique-name:"Name",label-value:"Name">;<label-unique-name:"Surname",label-value:"Surname">
<!-- For French -->
<label-unique-name:"Name",label-value:"nom">;<label-unique-name:"Surname",label-value:"nom de famille">
<!-- For English -->
<label-unique-name:"Name",label-value:"nombre">;<label-unique-name:"Surname",label-value:"apellido">
Please note : this is for understanding only, it's not a JSON.
Now using jQuery go through each label and replace the label's value. Hope it'll help you.
Issue 2 :
You can save the selected language's value in session, and generate your dropdown accordingly.
#Html.DropDownListFor(l => l.LanguageID, new SelectList(Model.Languages, "Value", "Text"), !string.isNullorEmpty(HttpContext.Current.Sessions["Language"]) ? HttpContext.Current.Sessions["Language"] : "Select Language", new { id = "LanguageId" ,onchange="GetLanguage()" })
The scenario I want to implement is stated as follows:
I am using MVC 3 with razor view.
On the click of text box (call it Result Text Box), open a dialog from the Home View (which is a different view, the Add View) and carrying a postback to Home controller action.
On the dialog (which is Add View), simply input two numbers for addition and on its submit, does a post-back on Add view controller action.
Now, when the Add controller action processing completes, I want to do the addition of the numbers and close the current dialog (Add View) and updating the Result Text Box present on the parent view (Home view) with the addition result.
Note: After closing the dialog I dont want the parent view to be reloaded or refreshed.
Now, Where I am facing the problem is how to
1) fetch hidden field value (container addition value) and set to the Result test box on parent page?
2) close the dialog(add view) from the dialog itself? without refreshing the parent view?
code:
<h2> Input numbers to add</h2>
#using (Html.BeginForm("About","Home",FormMethod.Post, new {id = "dialogchildform"}))
{
#Html.Hidden("hdnresult", ViewData["result"], new { id = "hdnres" })
<div style="position: relative; margin-left: 200px; top: 80px">
<fieldset>
#Html.ValidationSummary(true)
<div class="editor-label">
Value 1
</div>
<div class="editor-field">
#Html.EditorFor(model => model.num1, new { id = "num1" })
#Html.ValidationMessageFor(model => model.num1)
</div>
<div class="editor-label">
Value 2
</div>
<div class="editor-field">
#Html.EditorFor(model => model.num2, new { id = "num2" })
#Html.ValidationMessageFor(model => model.num2)
</div>
</fieldset>
<p>
<input type="submit" value="Add and Retrun" id="inputSubmit" />
</p>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$("#inputSubmit").click(function () {
document.forms('dialogchildform').submit();
// txtParentResult is a Textbox on prent view to be updated
document.getElementById('txtParentResult').value
= document.forms('dialogchildform').hdnres.value;
// not updating the parent textbox
// $(window.document).dialog('close');
//gives error - Microsoft JScript runtime error: Object doesn't support property or method 'dialog'
//$("#mydiag").dialog("close");
// also gives error
//jQuery(".ui-dialog-content").dialog("close");
// again gives error - Microsoft JScript runtime error: Object doesn't support property or method 'dialog'
});
});
</script>
Controller Action:
[HttpPost]
public ActionResult Add(AddNum vAddNum)
{
objAddNum = vAddNum;
int result = objAddNum.AddNumbers();
ViewData["_ActionCloseDialog"] = "true";
ViewData["result"] = result;
return View();
}
Got the solution.
Instead of using the jQuery function on the dialog view, I have used dialog buttons on the parent view itself.
Since, the dialog is defined as global varibale in javascript function on the parent .cshtml and encapsulates child view in the div, has access to controls on both the views.
Not sure if this is what your after but, In the child frame you can set a global variable and then set the controls text in the parent to the vatiable
parent.document.getElementById("").text() = "";
Then you can close the child frame by doing
var child = document.getElementById('childId');
child.document.close()
Hope this helps