Change view using ajax on drop-down list change event - c#

I need to change the view in same page using ajax when the user changes the option of the drop-down list.
Up until now in my view I have the drop down list
<div class="wrapper">
<div>
<label>Get cars per people </label>
#Html.DropDownList("ddlChange", new SelectList(ViewBag.OptionsList,"Value","Text", ViewBag.selectedValue),new { #id = "ddlChangeID" })
</div>
<div class="box box-success">
<div class="box-body">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
</div>
</div>
Then in a script (which I found from another question)
$(document).ready(function () {
$("#ddlChangeID").change(function () {
var strSelected = "";
$("#ddlChangeID:selected").each(function () {
strSelected += $(this)[0].value;
});
var url = "/Cars/Index/" + strSelected;
$.post(url, function (data) {
});
});
})
And in the controller I am using ViewBag values to save the drop-down list values and whatever else is needed for the graph which loads in a different script again with ViewBag values. I have managed to pass the selected value (strSelected) but the view does not reload with the new data.
How should I make the ajax event?

Change your script ajax call by calling an action result as follows
$("#ddlChangeID").change(function () {
$.ajax({
url: "/Controller/ActionHtml?id="+$('#ddlChange').val(),
type: "POST",
cache: false,
success: function (result) {
$("#myChart").html(result);
},
error: function () {
$("#myChart").empty();
}
});
});
and in the controller the actionresult will be like the following which returns the html partial view that you need to append
public ActionResult ActionHtml(string id)
{
//Here you can load the data based on the id,pass model to the patial views etc
ViewBag.id = id;
return PartialView("~/Views/Shared/myhtml.cshtml");
}
myhtml.cshtml will be a partial view with the html content as
//content is dummy,change the content as you want
<!DOCTYPE html>
<html>
<body>
<p>Enter some text in the fields below, then press the "Reset form" button to reset the form.</p>
<form id="myForm">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br><br>
</form>

So I changed the
#Html.DropDownList("ddlChange", new SelectList(ViewBag.OptionsList,"Value","Text", ViewBag.selectedValue),new { #id = "ddlChangeID" })
To
#Html.DropDownList("ddlChange", new SelectList(ViewBag.OptionsList,"Value","Text", ViewBag.selectedValue),new { #onchange = "ChangeOption()" })
adding also an id to the main div.
And the script to
function ChangeOption() {
var id = $('#ddlChange').val();
$.ajax({
url: '/Cars/Index',
type: "GET",
data: { Id: id },
success: function (data) {
$('#wrapAll').html(data);
}
});
}
It seems to work. Only issue now is that the css breaks.
It pushes the graph and drop-down list to the right breaking
the functionality.

Related

Refresh div content after OnGet method in Razor Pages

I've got 1 data in view which is assign in OnGet method as a ViewData.
OnGet method:
public void OnGet(string parameter = "default")
{
ViewData["SelectedParam"] = parameter;
}
My View:
#{
var selectedParam= ViewData["SelectedParam"];
}
<h1>Some Page</h1>
<hr />
<div class="row">
<div class="col-3">
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
#await Component.InvokeAsync("MyComponent")
</div>
</div>
<div class="col-9">
<div id="mainDiv">
#selectedParam
<hr />
#if (string.IsNullOrEmpty(selectedParam.ToString()))
{
<h5>No param selected</h5>
}
else
{
<h5>#selectedParam selected</h5>
}
</div>
</div>
</div>
My component is sending parameter, View is changing value of ViewData["SelectedParam"] and now I want to refresh the content of a div.
JQuery:
$(document).on('click', 'componentElement', function () {
var parameterResult = "test";
$.ajax({
url: '/Index',
type: 'get',
data: {
parameter: parameterResult
},
success: function () {
<!-- here I need to reload -->
}
});
});
I tried to do location.reload(), but I must refresh only this div, not the whole page, tried also with $('#mainDiv').load(' #mainDiv'), but still nothing
Razor evaluates the View and creates the HTML the client sees. If you examine the source code on Chrome for example, you'll notice all your Razor code was replaced with standard HTML.
If you want to modify the HTML after the page already loaded, you have 2 options. Reload page with new data, so new HTML will be created and the new conditions will be reevaluated, or use JS / JQuery to modify the page on the client side. JQuery won't have access to the ViewData though, this is pure HTML / JS. Since you don't want to reload the page, that's the only way.
Example of JQuery function that removes and adds stuff from the HTML:
$(document).on('click', 'componentElement', function () {
var parameterResult = "test";
$.ajax({
url: '/Home/OnGet/', //assuming controller would be Home
type: 'POST', //if you are sending data, it's a POST
dataType: "Json", //specify the datatype you are sending
data: {
parameter: parameterResult
},
success: function (obj) { //notice I'm expecting an object back here
$( "#mainDiv" ).empty(); //this will clear all the children inside the mainDiv
$( "#mainDiv" ).append("<h5<" + obj + " selected</h5>"); //this will add back the string you get your OnGet
}
});
});
And here is how your OnGet should be to respond to the ajax request:
public JsonResult OnGet(string parameter = "default") //I'll return a Json, so class needs to be JsonResult
{
return Json(parameter);
}

How to use AJAX on ASP.NET MVC RazorPage

I am trying to create a cascading DropDownList on ASP.NET RazorPage. After doing some research I found the most common way to do the task is utilizing jQuery in my View. Nearly all demos and examples I found online implement a cascading DropDownList in previous ASP.NET versions, more specifically MVC. I tried translating these examples in the context of how I need them but I am having no luck, most likely due to syntax errors and/or other reasons.
I am using ASP.NET Core 2.2
I am having trouble specifically implementing the dynamic function call (GetSubCategory) whenever an item is selected in the first DropDownList which is displaying correctly
<form asp-controller="my_dropdown" asp-action="CreatePortfolio" method="post" class="form-horizontal" role="form">
<div class="form-group">
<div class="row">
<div class="alert-danger" asp-validation-summary="ModelOnly"></div>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-4">
<label for="CategoryName">Category</label>
#Html.DropDownList("categorylist",
new SelectList((System.Collections.IEnumerable)ViewData["categorylist"], "CategoryId", "CategoryName"), "Select Category", "CategoryName")
<label for="SubCategoryName">Subcategory</label>
#section scripts{
<script type="text/javascript">
//Insert default item "Select" in dropdownlist on load
$(document).ready(function () {
var items = "<option value='0'>Select</option>";
$("#colorselect").html(items);
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#CategoryId").on("change", function () {
$list = $("#SubCategory");
$.ajax({
type: "GET",
url: '/CreatePortfolio',
data: { id: $("#CategoryId").val() },
traditional: true,
success: function (response) {
$list.empty();
$.each(result, function (i, item) {
$list.append('<option value="' + item["SubCategoryId"] + '"> ' + item["SubCategoryName"] + '</option>');
});
},
error: function () {
alert("Something went wrong"); // Hide loader icon
},
});
})
})
</script>
}
</div>
</div>
</div>
Code behind the view
public JsonResult GetSubCategory(int CategoryId)
{
subcategorylist = _context.GetAllSubCategories(CategoryId);
//ViewData["subcategorylist"] = subcategorylist;
return new JsonResult(subcategorylist);
}
public void OnGet()
{
// ----- Getting Data From Database Using Stored Procedure -----
categorylist = _context.GetAllCategoires();
// ----- Assigning categorylist to ViewData["categorylist"] in order to access it in the view -----
ViewData["categorylist"] = categorylist;
}
I want the code to correctly display the SubCategories associated to the Category by CategoryId which is a field in both classes/tables

ASP.NET foreach do not show items

When I select Date in DateTimePicker, it's invoking public ActionResult Index(DateTime? test). It returns some items into the view, but those items do not appear on Index. It seems that this does not work, and I'm unsure why:
<h1>Items</h1>
#foreach (var item in Model)
{
<br />#item.Date
}
Controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
List<Table> temp = new List<Table>();
return View(temp);
}
[HttpPost]
public ActionResult Index(DateTime? test)
{
masterEntities m = new masterEntities();
List<Table> temp = m.Table.Where(key => key.Date == test).Select(key => key).ToList();
return View(temp);
}
}
Index.cshtml:
#model IEnumerable<DatePicker.Models.Table>
#{
ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-2.2.0.min.js"></script>
<script src="~/Scripts/moment.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/bootstrap-datetimepicker.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$('#datetimepicker1').datetimepicker({ useCurrent: false });
$('#datetimepicker1').on("dp.hide", function (e) {
//var temp = $('#datetimepicker1').data('DateTimePicker').date().format('YYYY-MM-DD HH:mm')
$.ajax({
url: "/Home/Index",
type: "POST",
data: { test: $('#datetimepicker1').data('DateTimePicker').date().format('YYYY-MM-DD HH:mm') },
//data: {test: temp },
});
});
</script>
</div>
</div>
<h1>Items</h1>
#foreach (var item in Model)
{
<br />#item.Date
}
First you send an empty list to the view:
List<Table> temp = new List<Table>();
return View(temp);
So the loop doesn't show anything because, well, there's nothing to show. It's an empty list.
Then you make an AJAX request to get items:
$.ajax({
url: "/Home/Index",
type: "POST",
data: { test: $('#datetimepicker1').data('DateTimePicker').date().format('YYYY-MM-DD HH:mm') },
//data: {test: temp },
});
But you don't do anything with those items. You basically ignore the response from the AJAX request.
So... The data doesn't display because you haven't written any code to display the data. The AJAX request should have some sort of callback function to do something with the returned response:
$.ajax({
url: "/Home/Index",
type: "POST",
data: { test: $('#datetimepicker1').data('DateTimePicker').date().format('YYYY-MM-DD HH:mm') },
//data: {test: temp },
success: function (data) {
// do something with the response here
}
});
What you do with the response is up to you. Is it JSON? HTML? Based on the server-side code, it looks like it's HTML. So you can maybe put it into an element on the page. Something like this, perhaps:
$('#someElement').html(data);
That's just one example, and would of course require an element of some sort that you can identify to hold the response. You could do a lot of other things with the response.
One thing to note, however, is that your response appears to be an entire page. It includes script tags, link tags for CSS, and all sorts of markup that you otherwise already have on the client. So putting the entire page into an element isn't going to work right.
You might want to return just a partial view for this AJAX response. Or, otherwise, instead of using AJAX at all just navigate to the action to get that entire page.

ASP.NET MVC4 Ajax ActionLink helper doesn't work - reloads entire page with the returned partial view

I have a pretty simple index page for an MVC project which allows you to create "jobs" and edit existing jobs. I'm trying to use an Ajax link to replace the contents of a div with the job-edit form, which the Create() and Edit() actions return as a partial view. Instead, when you click on the Ajax links, the entire page content is replaced with the partial view, instead of just the contents of the appropriate div element. Here's the relevant .cshtml code:
#{
string placeholder = "777777";
}
<body>
<ol id="JobListing">
#Html.Partial("_ExportJobListingPartial", Model)
</ol>
<br /><br /><br />
#Ajax.ActionLink("New", "Create", new AjaxOptions { UpdateTargetId = "EditJobContainer", InsertionMode = InsertionMode.Replace, HttpMethod = "GET" })
<br /><br />
<div id="EditJobLinkContainer">
#Ajax.ActionLink("Edit", "Edit",
new { id = placeholder }, // Route values
new AjaxOptions { UpdateTargetId = "EditJobContainer", InsertionMode = InsertionMode.Replace, HttpMethod = "GET" }, // Ajax options
new { id = "EditJobLink" } // Html attributes
)
</div>
<br /><br />
<div id="EditJobContainer">
EMPTY BOX HERE
</div>
<br />
</body>
</html>
<script>
$(function() {
$("#JobListing").selectable({
selected: function (event, ui) {
// Select only one at a time
$(ui.selected).addClass("ui-selected").siblings().removeClass("ui-selected");
$("#EditJobLinkContainer").html('#Ajax.ActionLink("Edit", "Edit",
new { id = placeholder }, // Route values
new AjaxOptions { UpdateTargetId = "EditJobContainer", InsertionMode = InsertionMode.Replace, HttpMethod = "GET" }, // Ajax options
new { id = "EditJobLink" } // Html attributes
)');
$("#EditJobLink").click(UpdateOnClick);
}
});
$("#EditJobLink").click(UpdateOnClick);
function UpdateOnClick() {
//Get the id of the selected item
var id = $(".ui-selected").first().attr("name");
this.href = this.href.replace("#placeholder", id);
}
});
</script>
Most of the answers I've read online to similar questions suggest that maybe I'm not including the unobtrusive-ajax code correctly or in the right place. I have it in the _Layout view, before the RenderBody() call, as
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
I know this code is loading in because I inserted an alert() call into the unobtrusive-ajax.js file which launches on page load, and the links to the code in Chrome work fine. However, I had to manually replace the calls to live() with on() in the ajax scripts since live() is deprecated in the most recent version of jQuery, even though I'm pretty sure they're the latest scripts with MVC4. At one point the Ajax call was actually working for the "New" link, but I've made changes since, and nothing has been working for a few days now. Any help would be greatly appreciated.
I use empty dedicated div for that
the html is
<div id="targetDiv">
and the script is
$(".get-roles").live("click", function (e) {
$("#targetDiv").empty();
$.ajax({
url: "edit",
type: 'GET'
xhrFields: {
withCredentials: true
},
success: function (data) {
if (data) {
$("#targetDiv").append(data);
}
else {
$("#targetDiv").text("Error");
}
}
});
});
you need to include this in your page
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

Getting a local variable value using jQuery

I have a little problem when trying to get the value of a local int variable on a view, using jQuery. So, I have a the main view, and as you can see in the code below, I use a partial view named "_Result", when I try to get the value of indexPage by handling the click event of a button in the partial view, I get 0, event if I initialize my variable by another value(5 for example). Any idea why ?
Thanks in advance
My view :
#model System.Data.DataTable
#{var pageIndex = 5;}
<div>
<div>
<span>Téléphone ?</span>
<input id="idTxTel" type="text" name="txTelephone"/>
<input id="idBnSearch" type="submit" value="Chercher" name="bnSearch"/>
</div>
#Html.Partial("_Result", Model)
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#idBnSearch").click(function () {
//The right value (5)
alert('#pageIndex');
var telValue = $("#idTxTel").val();
var methodUrl = '#Url.Content("~/Search/GetReverseResult/")';
'#{pageIndex = 0;}'
doReverseSearch(telValue, '#pageIndex', methodUrl);
});
$("#bnNextPage").live("click", function ()
{
//Not th right value (0)
alert('#pageIndex');
});
});
</script>
My doReverseSearch method :
function doReverseSearch(telValue, pageIdx, methodUrl)
{
$.ajax(
{
url: methodUrl,
type: 'post',
data: JSON.stringify({ Telephone: telValue, pageIndex: pageIdx }),
datatype: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$('#result').replaceWith(data);
},
error: function (request, status, err) {
alert(status);
alert(err);
}
});
}
My partial view :
<div id="result">
<h2>Résultat de la recherche</h2>
<div>#ViewBag.CountResult entreprises trouvées</div>
#if(Model != null)
{
foreach (DataRow row in Model.Rows)
{
<h3>#row["CompanyName"]</h3>
}
}
<hr />
<div>
<span>Page N sur M</span>
<input id="bnPreviousPage" type="submit" value="Précédant" name="bnPrevious"/>
<input id="bnNextPage" type="submit" value="Suivant" name="bnNext"/>
</div>
</div>
Razor inside javascript has to be wrapped in a block
so you can do this:
<script>
// global value for page
<text>
var myPage = #pageIndex;
<text>
</script>
what would be far easier is give the button an attribute of data-page and ask for attribute in click event:
<button data-page="#("pageIndex")" id="myButt" />
$("#myButt").on("click",function(e){
var pageIndex = $(this).attr("data-page");
alert(pageIndex);
});

Categories