passing a variable from cshtml razor to jquery - c#

I have a partial view that I am calling on pages as follows :-
#Html.Partial("~/Views/Shared/ImageGallery.cshtml", Model)
The code for the actual Jquery of this page is a s follows :-
<script type="text/javascript">
$(document).ready(function () {
$('.modal_block').click(function (e) {
$('#tn_select').empty();
$('.modal_part').hide();
});
$('#modal_link').click(function (e) {
$('.modal_part').show();
var context = $('#tn_select').load('/Upload/UploadImage?Page=Article&Action=Edit&id=16', function () {
initSelect(context);
});
e.preventDefault();
return false;
});
});
</script>
Now this works perfectly, however I need to find a way to pass dynamic vars instead of hard coded vars to this :-
Upload/UploadImage?Page=Article&Action=Edit&id=16
In the Model I have all the vars, however I do not know how I can insert them into the Jquery. Any help would be very much appreciated!
---------UPDATE-----------------------
This is the code I am putting into each cshtml that needs the ImageGallery.
</div>
#Html.HiddenFor(model => model.PageViewModel.Page.PageTitle, new { id = "PageTitle"});
#Html.HiddenFor(model => model.PageViewModel.Page.PageAction, new { id = "PageAction"});
#Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID, new { id = "ArticleID"});
<div>
#Html.Partial("~/Views/Shared/ImageGallery.cshtml", Model)
</div>
New Javascript in the ImageGallery :-
<script type="text/javascript">
var pageTitle = $('#PageTitle').val();
var pageAction = $('#PageAction').val();
var id = $('#ArticleID').val();
$(document).ready(function () {
$('.modal_block').click(function (e) {
$('#tn_select').empty();
$('.modal_part').hide();
});
$('#modal_link').click(function (e) {
$('.modal_part').show();
var context = $('#tn_select').load('/Upload/UploadImage?Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id, function () {
initSelect(context);
});
e.preventDefault();
return false;
});
});
</script>
This works fine now

You can add hidden field to your view and bind data form the model. Then you can easily read this value from jQuery.
View:
#Html.HiddenFor(model => model.Id, new { id = "FieldId"});
Script:
var id= $('#FieldId').val();
Also you can put this hiddens into your partial view. If your partial view is not strongly typed change HiddenFor to Hidden. Your ImageGallery partial view should contain the following div:
</div>
#Html.Hidden("PageTitle", Model.PageViewModel.Page.PageTitle);
#Html.Hidden("PageAction", Model.PageViewModel.Page.PageAction);
#Html.Hidden("ArticleID", Model.ArticleViewModel.Article.ArticleID);
<div>
In this case you don't need to put hiddens to every cshtml that needs the ImageGallery.

You can either set hidden fields or just declare javascript variables and set their values from either your model or the Viewbag, just like:
var action = #Model.action;
or
var id = #ViewBag.id;
and you can just use it in your code
<script type="text/javascript">
var action = #Model.action;
var id = #ViewBag.id;
$(document).ready(function () {
$('.modal_block').click(function (e) {
$('#tn_select').empty();
$('.modal_part').hide();
});
$('#modal_link').click(function (e) {
$('.modal_part').show();
var urlToLoad = "/Upload/UploadImage?Page=Article&Action=" + action + "&id=" + id;
var context = $('#tn_select').load(urlToLoad, function () {
initSelect(context);
});
e.preventDefault();
return false;
});
});

The following is another solution. I was in need of passing my api url declared in web.config to JavaScript (in this case Jquery)
In Razor declare a variable
#{var apiUrl= #System.Configuration.ConfigurationManager.AppSettings["BlogsApi"];}
Then in JavaScript
var apiUrl = '#apiUrl';

Related

Jquery click doesn't work twice

I'm trying to write CRUD operations using ajax. Here some code:
These are my View classes:
//PhotoSummary
#model PhotoAlbum.WEB.Models.PhotoViewModel
<div class="well">
<h3>
<strong>#Model.Name</strong>
<span class="pull-right label label-primary">#Model.AverageRaiting.ToString("# stars")</span>
</h3>
<span class="lead">#Model.Description</span>
#Html.DialogFormLink("Update", Url.Action("UpdatePhoto", new {photoId = #Model.PhotoId}), "Update Photo", #Model.PhotoId.ToString(), Url.Action("Photo"))
</div>
//Main View
#model PhotoAlbum.WEB.Models.PhotoListViewModel
#{
ViewBag.Title = "My Photos";
}
#foreach (var p in #Model.Photos)
{
<div id=#p.PhotoId>
#Html.Action("Photo", new {photo = p})
</div>
}
The sript:
$('.dialogLink').on('click', function () {
var element = $(this);
var dialogTitle = element.attr('data-dialog-title');
var updateTargetId = '#' + element.attr('data-update-target-id');
var updateUrl = element.attr('data-update-url');
var dialogId = 'uniqueName-' + Math.floor(Math.random() * 1000)
var dialogDiv = "<div id='" + dialogId + "'></div>";
$(dialogDiv).load(this.href, function () {
$(this).dialog({
modal: true,
resizable: false,
title: dialogTitle,
close: function () { $(this).empty(); },
buttons: {
"Save": function () {
// Manually submit the form
var form = $('form', this);
$(form).submit();
},
"Cancel": function () { $(this).dialog('close'); }
}
});
$.validator.unobtrusive.parse(this);
wireUpForm(this, updateTargetId, updateUrl);
});
return false;
});});
function wireUpForm(dialog, updateTargetId, updateUrl) {
$('form', dialog).submit(function () {
if (!$(this).valid())
return false;
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$(dialog).dialog('close');
$(updateTargetId).load(updateUrl);
} else {
$(dialog).html(result);
$.validator.unobtrusive.parse(dialog);
wireUpForm(dialog, updateTargetId, updateUrl);
}
}
});
return false;
});
}
And here my Tag builder:
public static MvcHtmlString DialogFormLink(this HtmlHelper htmlHelper, string linkText, string dialogContentUrl,
string dialogTitle, string updateTargetId, string updateUrl)
{
TagBuilder builder = new TagBuilder("a");
builder.SetInnerText(linkText);
builder.Attributes.Add("href", dialogContentUrl);
builder.Attributes.Add("data-dialog-title", dialogTitle);
builder.Attributes.Add("data-update-target-id", updateTargetId);
builder.Attributes.Add("data-update-url", updateUrl);
builder.AddCssClass("dialogLink");
return new MvcHtmlString(builder.ToString());
}
So, I have major problem if the dialog was called twice without the calling page being refreshed:
it just redirects me to the action page.
The question is how to update #Html.Action without reloading the page?
Could anyone help me?
Your #foreach loop in the main view is generating a partial view for each Photo which in turn is creating a link with class="dialogLink".
Your script handles the click event of these links and replaces it with a new link with class="dialogLink". But the new link does not have a .click() handler so clicking on the new (replacement) link does not activate your script.
Instead you need to use event delegation to handle events for dynamically generated content using the .on() method (refer also here for more information on event delegation). Note also that your current use of $('.dialogLink').on('click', function () { is the equivalent of $('.dialogLink').click(function () { and is not using event delegation. It attaches a handler to elements that exist in the DOM at the time the page is loaded, not to elements that might be added in the future.
Change your html to
<div id="photos">
#foreach (var p in #Model.Photos)
{
<div class="photo">#Html.Action("Photo", new { photo = p })</div>
}
</div>
and then modify the script to
$('#photos').on('click', '.dialogLink', function() {
....
});
Side note: There is no real need to add an id=#p.PhotoId to the containing div element and you could use <div class="photo"> as per above, and then reference it by using var updateTargetId = $(this).closest('.photo'); and delete the builder.Attributes.Add("data-update-target-id", updateTargetId); line of code from your DialogFormLink() method

DropdownList does not pass value but triggers script. DropdownListFor passes value but does not trigger script

I have this script in my view (this is the source):
<script type="text/javascript" src="../../Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#state").prop("disabled", true);
$("#country").change(function () {
if ($("#country").val() != "Please select") {
var options = {};
options.url = "/companies/getbolag";
options.type = "POST";
options.data = JSON.stringify({ country: $("#country").val() });
options.dataType = "json";
options.contentType = "application/json";
options.success = function (states) {
$("#state").empty();
for (var i = 0; i < states.length; i++) {
$("#state").append("<option>" + states[i] + "</option>");
}
$("#state").prop("disabled", false);
};
options.error = function () { alert("Fel vid bolagshämtning!"); };
$.ajax(options);
}
else {
$("#state").empty();
$("#state").prop("disabled", true);
}
});
});
</script>
It populates a second dropdown list based on what is selected in the first. Cascading dropdowns.
This HtmlHelper triggers the script but when submitted omits the value:
#Html.DropDownList("country", ViewData["kundLista"] as SelectList)
This one does the opposite, it submits the value but does not trigger the script:
#Html.DropDownListFor(model => model.Kund, ViewData["kundLista"] as SelectList)
I need it to both trigger the script and submit the value. How do I do this?
Since the name of your property is Kund, second helper creates a select element which has both id and name fields set to Kund. On the other hand your script uses id country to address this select. So you have two options:
Change id used in the script to #Kund:
$("#Kund").change(function () {
if ($("#Kund").val() != "Please select") {
Use first helper with correct name and id:
#Html.DropDownList("Kund", ViewData["kundLista"] as SelectList), new {#id="country"})
if you look at the rendered html the drop down list for is creating an id of Kund which won't match your script. I would recommend putting a class on your drop downs that won't change
#Html.DropDownListFor(x => x.Kund, selectlist, new { #class = "Kund" })
then in your script change your selector from #country to .Kund
Drop down list for will tie the drop down to your model which is why you are getting the passed value. For the other drop down if you create a List and pass that to the view you can set the selected item there and that will hopefully set the drop down list for you

C# MVC4: Replace <div> when selection is made from a Html.DropDownList using jQuery

I need to be able to populate data into a <div> or some other sort of section from an object after the corresponding string has been selected from a drop down list (lazy loading).
When a chnage is made in the dropdownlist, I want the method in my controller to be called which will fill in <div id=result></div> with the output from the method.
Perhaps I am approaching this problem wrong.
I suspect the problem is in my JavaScript.
Here is my approach:
View:
<div>#Html.DropDownList("MyDDL") </div>
<br>
<div id="result"></div>
JavaScript:
<script type ="text/javascript">
$(document).ready(function () {
$("#MyDDL").change(function () {
var strSelected = "";
$("#MyDDL option:selected").each(function () {
strSelected += $(this)[0].value;
});
var url = "HomeController/showInfo";
//I suspect this is not completely correct:
$.post(url, {str: strSelected},function (result) {
$("result").html(result);
});
});
});
</script>
Controller (Perhaps I shouldn't be using PartialViewResult):
public ActionResult Index()
{
List<string> myList = new List<string>();
List<SelectListItem> MyDDL = new List<SelectListItem>();
myList.Add("Tim");
myList.Add("Joe");
myList.Add("Jim");
//fill MyDDL with items from myList
MyDDL = myList
.Select(x => new SelectListItem { Text = x, Value = x })
.ToList();
ViewData["MyDDL"] = MyDDL;
return View();
}
[HttpPost]
public PartialViewResult showInfo(string str)
{
Person p = new Person(str); //name is passed to constructor
p.LoadInfo(); //database access in Person Model
ViewBag.Info = p.Info;
return PartialView("_result");
}
_result.cshtml:
<p>
#ViewBag.Info
</p>
Thanks You.
Change your script a little bit. Missing a # in the jQuery selecter for result div . Use the code given below
$.post(url, {str: strSelected},function (result) {
$("#result").html(result);
});
In my opinion if the javascript are in local don't need put $.post(url, {str: strSelected},function (result) {
You can use
//I suspect this is not completely correct:
$("#result").html(result);
try it
Did you try debugging p.LoadInfo() if it has any value? I also have some suggestions for your script:
Try adding keyup in your event so you can get the value in cases when the arrow keypad is used insted of clicking:
$("#MyDDL").on("change keyup", function () {
// you can get the dropdown value with this
var strSelected = $(this).val();
So I made the following changes and it worked:
View:
<div><%= Html.DropDownList("MyDDL") %> </div>
<br>
<span></span>
JavaScript:
<script type ="text/javascript">
$(document).ready(function () {
$("#MyDDL").change(function () {
var strSelected = $("#MyDDL option:selected").text();
var url = "/Home/showInfo";
$.post(url, {str: strSelected},function (result) {
$("span").html(result);
});
});
});
_result.cshtml:
#ViewBag.Info
The Controller was left unchanged.

Url.Action Not figuring out the actual url

I am trying to use Url.Action to generate the correct HTTP URL based on a controller action like this :
$.post('#Html.Raw(Url.Action("Delete", new { id = "1" }))')
However, it is not working as expected . The actual url fired (got this from dev tools) is
http://localhost:60223/CordBlood/#Html.Raw(Url.Action(%22Delete%22,%20new%20%7B%20id%20=%20%224%22%20%7D))
Whereas I want something like this :
http://localhost:60223/CordBlood/Delete/1
What am I doing wrong here?
I think you are trying to achieve something similar to this
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#dropdown").change(function () {
var id = $("#dropdown").val();
if (id == "")
{ id = 0; }
var dataToSend = {
Id: id
};
RedirectToPage(id);
});
function RedirectToPage(id) {
var url = '#Url.Action("Delete", "yourController", new { Id = "__id__" })';
window.location.href = url.replace('__id__', id);
}
});
</script>
Hope this will give you some idea

Passing Object From Controller to JavaScript JQuery

This is driving me crazy. All I'm trying to do is to pass in a Id to a ActionMethod which is working and have an Object be returned to the javascript. Then in javascript, I want to be able to say something like..Objec.Property, ie/ Student.Name, or Student.GPA.
Any help is appreciated. I tried json but couldn't get that to work either.
ActionResult:
[AcceptVerbs(HttpVerbs.Get)]
public Epic GetEpicPropertyDetails(int id)
{
var Epictemplist = epicRepository.Select().Where(x => x.Id.Equals(id));
return Epictemplist.SingleOrDefault();
}
javascript:
<script type="text/javascript">
$(document).ready(function () {
$(".ListBoxClass").click(function (event) {
var selectedid = $(this).find("option:selected").val();
event.preventDefault();
$.get("/Estimate/GetEpicPropertyDetails", { id: selectedid }, function (result) {
$(".TimeClass").val(result);
});
});
});
</script>
result.Name is obviously wrong I just dont know how to call this the right way.
Tman, I had a similiar issue that Darin helped me with. I needed to add a $.param to my getJSON. Check out this post MVC ListBox not passing data to Action
try changing your method like this
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetEpicPropertyDetails(int id)
{
var Epictemplist = epicRepository.Select().Where(x => x.Id.Equals(id)).SingleOrDefault();
return Json(Epictemplist, JsonRequestBehavior.AllowGet);
}
Than from your JS
<script type="text/javascript">
$(document).ready(function () {
$(".ListBoxClass").click(function (event) {
var selectedid = $(this).find("option:selected").val();
event.preventDefault();
$.get("/Estimate/GetEpicPropertyDetails", { id: selectedid }, function (result) {
$(".TimeClass").val(result.Name);
}, 'json');
});
});
</script>

Categories

Resources