I have 2 drop-downs city and state and zip code textbox. I need to generate city and state drop-downs based on zip code entered. When a user enters zip code I am passing zip code to my API to get state/city list.
with the below code I am able to get he data from my API and can see the state/city in the console but i not able to display in drop down. I am not sure what I am missing. How do I display data in drop drown list.
API controller :
public class Getstatelist : ApiController
{
// GET api/Getstatelist/5
public List<CityState> GetCityState(string zipEntered)
{
var list = new List<CityState>();
if (string.IsNullOrEmpty(zipEntered) || zipEntered.Length < 2)
return list;
zipEntered += "%";
using (var connection = new OracleConnection(ConfigurationManager.ConnectionStrings["MY_DB_CONNECTION_STRING"].ConnectionString))
{
connection.Open();
var sqlQuery = "select state from state_city_data where zip like :zipEntered";
using (var command = new OracleCommand(sqlQuery, connection))
{
command.BindByName = true;
command.Parameters.Add("zipEntered", OracleDbType.Varchar2).Value = zipEntered;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
list.Add(new CityStateZip
{
State = reader["STATE"] != DBNull.Value ? Convert.ToString(reader["STATE"]) : null,
});
}
}
}
}
return list;
}
}
$(document).ready(function ()
{
$("#zip").keyup(function () {
var el = $(this);
if (el.val().length === 5) {
$.ajax({
type:'GET',
url: "../api/Getstatelist/" + el.val(),
success: function (html) {
console.log(html);
$('#state').html(html);
}
});
}else{
$('#state').html('<option value="">Enter Zip code first </option>');
}
});
});
<div>
<div class="city-wrap">
<select id="city">
<option value="">Select City first</option>
</select>
<label for="city">City</label>
</div>
<div class="state-wrap">
<select id="state">
<option value="">Select State </option>
</select>
<label for="state">State</label>
</div>
<div class="zip-wrap">
<input type="text" pattern="[0-9]*" maxlength="5" required name="zip" id="zip" >
<label for="zip">Zip</label>
</div>
</div>
For populating state drop down, u need to modify your success callback in ajax as follows:
$.each(html,function(key,value){
$('#state').append($('<option></option>').val(value.State).html(value.State));
});
For city drop down also similarly:
$.each(html,function(key,value){
$('#city').append($('<option></option>').val(value.City).html(value.City));
});
Related
I have a DropDownListFor in my view that selects a date from a list of dates on the server. When I use a jQuery .on "change" $.post operation to post the date I select back to the controller, it correctly gets the updated data value from the server and updates the view model, but then it doesn't get displayed in the browser. It keeps the previous value instead. But if I click a submit button in the view's form instead, it correctly updates the data field with the data from the server. How I post the dropdown list selection determines whether my data field updates correctly or not.
Does anyone have any suggestions on how I can get the jQuery post to update my data field in the view instead of keeping the previous value ?
Here's my View Model:
public class HtmlData
{
public string FileDateListSelection { get; set; }
public List<SelectListItem> FileDateList { get; set; }
public string ServerData { get; set; }
public HtmlData(string selectedDate, List<SelectListItem> fileDateList, string serverData)
{
FileDateListSelection = selectedDate;
FileDateList = fileDateList;
ServerData = serverData;
}
}
Here's my View:
#model MvcJqueryTest.Models.HtmlData
#using (Html.BeginForm("SubmitButtonDateChange", "Home", FormMethod.Post, new { id = "dateSelectionForm" }))
{
<div class="row">
<div class="col-md-4">
<div id="dateList">
#Html.DropDownListFor(m => m.FileDateListSelection, Model.FileDateList)
</div>
</div>
<div class="col-md-2">
<div id="buttons">
<input type="submit" name="submit" value="Fetch" id="fetchButton" />
<input type="submit" name="submit" value="Reset" id="resetButton" />
</div>
</div>
</div>
}
<div class="row">
<div class="col-md-8">
<br />
<h3>#Model.ServerData</h3>
<br />
</div>
</div>
<script type="text/javascript">
$('#FileDateListSelection').on("change", function () {
var menuDateSelected = $('#FileDateListSelection').val();
$.post(
'#Url.Action("JqueryDateChange", "Home")',
{ selectedDate: menuDateSelected },
function (response) {
}
);
});
</script>
Here's my Home Controller Methods:
public ActionResult Index(string dateString)
{
DateTime compareTime = DateTime.Today;
if (!string.IsNullOrEmpty(dateString))
compareTime = DateTime.Parse(dateString);
string quote = "Now is the winter of our discontent";
if (compareTime < DateTime.Today)
quote = "Made glorious summer by this sun of York";
string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);
HtmlData hd = new HtmlData(selectedDate, dateList, quote);
return View(hd);
}
[HttpPost]
public ActionResult SubmitButtonDateChange(string FileDateListSelection, string submit)
{
string selectedDate = FileDateListSelection;
if (submit.Equals("Reset", StringComparison.OrdinalIgnoreCase))
selectedDate = DateTime.Now.Date.ToString("d", CultureInfo.GetCultureInfo("en-US"));
return RedirectToAction("Index", "Home", new { dateString = selectedDate });
}
[HttpPost]
public ActionResult JqueryDateChange(string selectedDate)
{
return RedirectToAction("Index", "Home", new { dateString = selectedDate });
}
The GetDateList method just returns a SelectListItem list of dates of files in a folder for the dropdown list, and selects one date as the selected item in the list. If the selected date is before today, the h3 tag containing the view model's "ServerData" property in the view shows "Now is the winter of our discontent". If the selected date is after midnight today, the h3 tag shows "Made glorious summer by this sun of York".
When I change the selection in the dropdown list, the JqueryDateChange controller method executes, and does a RedirectToAction to the Index method with the selected date as a parameter, which fills in the view model with the correct data for the "ServerData" property. But the "ServerData" value in the model is not displayed in the browser. It always retains the previous value, even though I can see the correct value there in the debugger when I set a break on <h3>#Model.ServerData</h3> in the view.
When I click the Fetch or Reset buttons in the view's form, the SubmitButtonDateChange controller method executes, and also does a RedirectToAction to the Index method with the selected date as a parameter. That also fills in the view model with the correct value for the "ServerData" property, but then it is correctly updated in the browser, showing the new value based on the dropdown list selection.
I was originally using $.ajax to post the new dropdown list suggestion, but that had the same problem. I also tried moving the "#Model.ServerData" inside the Form's curly brackets, but that didn't help, either. I found some info about ModelState that I thought might help, but when I looked at it in the debugger, it only had one key/value pair for the dateString parameter, so I couldn't see how to use it to fix the problem.
I think a AJAX solution would suffice to your scenario. You can do the following.
First, define a unique id for your HTML element, where you would show the value of ServerData:
<div class="row">
<div class="col-md-8">
<br />
<h3 id="serverDataID">#Model.ServerData</h3>
<br />
</div>
</div>
Then you need to define your AJAX call like this:
<script type="text/javascript">
$('#FileDateListSelection').on("change", function () {
var menuDateSelected = $('#FileDateListSelection').val();
var json = {
menuDateSelected: menuDateSelected
};
var options = {};
options.url = "#Url.Action("JqueryDateChange", "Home")";
options.type = "POST";
options.data = {"json": JSON.stringify(json)};
options.dataType = "json";
options.success = function (data) {
if (data.status == "true") {
$('#serverDataID').html(data.quoteString);
}
else {
alert("Some Error");
}
};
options.error = function (data) {
alert("Error while calling function");
console.log(data);
};
$.ajax(options);
});
</script>
And your Controller method will return a JsonResult to handle the callback:
using System.Web.Script.Serialization;
[HttpPost]
public JsonResult JqueryDateChange(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
var dateString = Convert.ToString(jsondata["menuDateSelected"]);
DateTime compareTime = DateTime.Today;
if (!string.IsNullOrEmpty(dateString))
compareTime = DateTime.Parse(dateString);
string quote = "Now is the winter of our discontent";
if (compareTime < DateTime.Today)
quote = "Made glorious summer by this sun of York";
string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);
return Json(new { status = "true", quoteString = quote }, JsonRequestBehavior.AllowGet);
}
I have not worked with Ajax so far and I want to show the price after selecting the desired option without refreshing the page.
<div class="form-group">
<label class="control-label">choice your Option</label>
<select>
#foreach (var item in Materials)
{
<option value="#item.Id">
#item.MaterialName #item.Panel
</option>
}
</select>
<span class="main-price ">#item.Price</span>
</div>
Lets see what we can do here for your case:
Assign an id to your select to hold the value that you will send your server and span to display the output from the server:
<div class="form-group">
<label class="control-label">choice your Option</label>
<select id="ddlMaterial">
#foreach (var item in Materials)
{
<option value="#item.Id">
#item.MaterialName #item.Panel
</option>
}
</select>
<span class="main-price" id="priceDisplay">#item.Price</span>
</div>
Now we define the AJAX call that will send the request to the server. This request will get the current id of the selected option and then covert it to a JSON string which is sent to the server for processing. The url is the action method which will be invoked on this call:
$(document).ready(function () {
$("#ddlMaterial").change( function (event) {
var id = $(this).val();
var json = {id : id};
$.ajax({
type: 'POST',
url: "#Url.Action("GetPrice", "Home")",
dataType : "json",
data: {"json": JSON.stringify(json)},
success: function(data) {
if(data.status=="true")
{
$("#priceDisplay").text(data.price);
}
else
{
alert('Some error');
}
},
error: function(data) {
alert('Some error');
window.location.reload();
}
});
});
});
And finally your Controller action method will be:
using System.Web.Script.Serialization;
[HttpPost]
public JsonResult GetPrice(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
var id = Convert.ToInt32(jsondata["id"]);
//Get the price based on your id from DB or API call
var getMyPrice=GetPrice(id);
return Json(new {status="true", price= getMyPrice});
}
Im making a page in razor pages asp.net c# where i want to show the values of the postgresql table, and when there is something new inserted you see the new updated table on the page without refreshing (live). I know that it probably has to do something with the notify and listen functions, but i could not find any good examples on the internet. I am a little stuck. Hope someone can show me a simple way of how to do it.
Here is the c# code:
public List<NotificationModel> ShowNotification()
{
var cs = Database.Database.Connector();
List<NotificationModel> not = new List<NotificationModel>();
using var con = new NpgsqlConnection(cs);
{
string query = "Select datumnu, bericht FROM notification ORDER BY datumnu DESC OFFSET 1";
using NpgsqlCommand cmd = new NpgsqlCommand(query, con);
{
cmd.Connection = con;
con.Open();
using (NpgsqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
not.Add(new NotificationModel { Datenow = ((DateTime) dr["datumnu"]).ToString("yyyy/MM/dd"), Bericht = dr["bericht"].ToString() });
}
}
con.Close();
}
}
return not;
}
And here is the html
<div class="container-fluid">
<p id ="output"></p>
<div class="col-3 bg-light">
<h5 class="font-italic text-left">Old Messages</h5>
<hr>
#foreach(var n in #Model.ShowNotification())
{
<tr>
<img class="img-fluid" src="/Images/Reservation.png"/>
<td>
#Html.DisplayFor(m => n.Datenow)
</td>
<td>
#Html.DisplayFor(m => n.Bericht)
</td>
</tr>
}
<hr>
</div>
</div>
</div>
One thing that you can do is to make ajax calls on mouse drag, first load some x number of records and show it in UI, later whenever user moves down call an ajax call on demand and send page number kind value and fetch to display on UI.
<script type="text/javascript">
$(document).ready(function () {
var serviceURL = '/ControllerName/GetData';
$.ajax({
type: "POST",
url: serviceURL,
data: param = "", //send page number here
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successFunc,
error: errorFunc
});
function successFunc(data, status) {
console.log(data); // append this to your table as applicable
}
function errorFunc() {
alert('error');
}
});
</script>
public class ControlllerName : Controller
{
//
// GET: /AjaxTest/
public ActionResult Index()
{
return View();
}
public ActionResult Getdata(int pagenumber)
{//fetch here the data based on pagenumber
return Json("chamara", JsonRequestBehavior.AllowGet);
}
}
I have the following idea that i am trying to implement
#foreach (var item in Model)
{
<div>User: #item.Name<br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit");
#Html.ActionLink("Update item", "updateMyItem", new { name = item.Name, lastvisit=????? })
</div>
}
I have seen this SO question Pass text in query string, but that is not what i want..
so my question is ..
in the above code how can I replace the (?????) with the value of the textbox(lastvisit)
and send the value as a querysting in the URL of the action link ??
Notice that I opted not to use a webform for my own reason and I know how to do it with webform.submit(), but my main concern is how to extract the value of #HTMLhelper.textbox()..
:)
Something like this might help. For this to work you need to render unique IDS for the links and textboxes.
Here is an example
Action method with a simple model
public ActionResult Index(int? id)
{
List<MyModel> mod = new List<MyModel>() {
new MyModel { SelectedValue = 1 } ,
new MyModel {SelectedValue = 2},
new MyModel {SelectedValue = 3}
};
return View(mod);
}
And this is the view with the script.
#model List<MVC3Stack.Models.MyModel>
#{
ViewBag.Title = "Home Page";
var i = 1;
}
<h2>#ViewBag.Message</h2>
<script type="text/javascript">
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "&lastvisit=" + $(this).val());
}
});
});
</script>
#foreach (var item in Model)
{
#Html.TextBox("lastVisit" + i, item.SelectedValue )
#Html.ActionLink("TestLink", "Index", "Home", new { id = "testLink" + i });
<br />
i++;
}
<input type="button" value="GetFile" id="getFile" />
here is a snapshot with the changed link
Hope this helps.
EDIT
My bad. Here is the update javascript which can do the trick.
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
$(this).change(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "?lastvisit=" + $(this).val());
}
});
});
});
Ok Nilesh I will answer my own question.. but I will cheat from your solution lol cuz it is inspiring .. thanx in advance
<script type="text/javascript">
$(document).ready(function () {
var myMainPath = "updateMyItem";
$("a").each(function(){
var name =$(this).parent("div").child("#itemName").val();
var visit = $(this).parent("div").child("#lastvisit").val();
$(this).attr('href', myMainPath +'?name=' + name + '&lastVisit='+ visit);
});
});
</script>
#foreach (var item in Model)
{
<div>User: <span id="itemName">#item.Name</span><br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit", new { id="lastvisit"});
Update item
</div>
}
you see it can be done by javascript , but i was mistaken to think that you can manipulate it via Razor on the server ..
I know this post is old, but i just started learning MVC thanks to the asp.net/mvc/ website and i faced a similar problem during the tutorial. My Index action expects 2 parameters which define sorting and filtering (through the macthing of a substring) of a set of record displayed in the view. My problem is that i can't sort a filtered subset, since the view is called but no parameter for filtering is passed once i activate the sorting clicking on the link of the header.
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString){...}
I thought i needed to access the TextBox, but apparently i just need to use the provided ViewBag object as already seen in this example!
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, searchString = ViewBag.SearchString })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString)
{
ViewBag.SearchString = searchString;
. . .
}
Maybe a similar behaviour could have been used for solving the problem that originated this post, i don't know.
There are many topics with this title, but none have helped me resolve my issue. I am new to MVC and jQuery, so my guess is there is something syntactically wrong with my approach. Any help is greatly appreciated.
I have a web application where I have an upper and a lower section on my page (both divs). My goal is to select a record in the top div (user list) and have the bottom section display a list of challenge questions that the user can fill in answers for. The list below is injected in using jquery based on the record selected in the top grid. Here's the code I am using to do this.
View - javascript:
function editModeratorSecurity(aPersonId) {
$.ajax({
url: '/Admin/GetAdvSecurity/' + aPersonId,
type: 'POST',
progress: showModSearchProgress(),
success: function (result) {
AdvancedSuccess(result);
},
error: function (result) {
AdvancedFailure(result);
}
});
}
function showModSearchProgress() {
$("#ModeratorDetail").hide();
$("#progressMod").show();
}
function endModProgress() {
$("#progressMod").hide();
$("#ModeratorDetail").show();
}
function AdvancedSuccess(result) {
$('#ModeratorDetail').html(result);
endModProgress();
}
function AdvancedFailure(result) {
endModProgress();
}
Controller:
public PartialViewResult GetAdvSecurity(string id)
{
//ID is the iD from the person table
PersonModelBuilder pmb = new PersonModelBuilder(CurrentSession.AccountId);
PersonEditModel pers = pmb.GetPersonToEdit(new Guid(id));
if (pers != null)
{
AdvancedSecurityModel sec = new AdvancedSecurityModel();
UserModelBuilder umb = new UserModelBuilder();
//Need to get the ID from the login table - using the email address
UserModel selUser = umb.CurrentUser(pers.EmailAddress);
//Need to get the challenge questions/answers for the selected users
List<UserQuestionModel> theQ = umb.GetUserChallengeQuestions(selUser.LoginId);
sec.theUser = selUser;
sec.theQuestions = theQ;
return PartialView("_UserChallengeQuestions",sec);
}
else
{
return PartialView("_UserChallengeQuestions", new AdvancedSecurityModel());
}
}
So - this call to the controller returns the partial view and I am populating the list of questions using the following code in the partial view:
#model AdvancedSecurityModel
<form id="frmChallengeQuestions" class="inlineForm">
<div style="min-height: 100px; max-height: 400px;overflow: hidden" >
<table width="100%">
<tr>
<td align="right"><input type="button" value="Save Changes" onclick="ValidateAndSave()"/> </td>
</tr>
<tr>
<td>
#{
string sInstruction = "";
string isChecked="";
string isDisplay = "none";
if (Model.theUser.SecondLevelAuthReqd)
{
isChecked = "checked='true'";
isDisplay = "";
sInstruction = "<br> Please answer <strong>at least 5</strong> of the questions below to set up this feature...";
}
}
2nd Authentication <input type="checkbox" id="2ndAuth" onclick="javascript:ToggleQuestions()" #isChecked/>
<br /> Checking this means that you will be required to answer a random challenge question from the questions you answer in the<br/> list below each time you log in.
<span id="spnExplanation"></span>
<p> </p>
<div id="theQuestionsandAnswers" style="display: #isDisplay; max-height: 175px;overflow-y: scroll" >
<table width="100%">
#{
if (Model.theQuestions != null)
{
int iCount = 0;
foreach (UserQuestionModel ques in Model.theQuestions)
{
string theAnswer = "";
iCount += 1;
if (ques.UserAnswer != null)
{
NLxCommon.Encryption enc = new NLxCommon.Encryption();
theAnswer = enc.Decrypt256(ques.UserAnswer);
enc.Dispose();
enc = null;
}
<tr>
<td width="5%"> </td>
<td>#ques.QuestionText</td>
<td><input id="Answer_#iCount" type="text" value="#theAnswer" /></td>
<td>
<input id="UserQuestionId_#iCount" type="hidden" value="#ques.UserQuestionId">
<input id="QuestionId_#iCount" type="hidden" value="#ques.QuestionId">
<input id="UserId_#iCount" type="hidden" value="#Model.theUser.LoginId">
</td>
<td width="5%"> </td>
</tr>
}
}
}
</table>
</div>
</td>
</tr>
</table>
</div>
</form>
In the loop, I am naming my controls - input id="Answer_#iCount" - Where iCount is the number of the question - from 1 to x.
The input button is an attempt to save the changes I made to the answers of the questions listed. The javascript function is listed below.
var numQ = #Model.theQuestions.Count;
function ValidateAndSave() {
var NumAnswers = 0;
for (i=1;i<=numQ;i++) {
var answer = "#Answer_" + i.toString();
var theAnswer = $(answer).val();
if (theAnswer != "") {
NumAnswers += 1;
}
}
if (NumAnswers < 5) {
alert('You must answer at least 5 questions to enable this feature');
return false;
}
//Answered the right number of questions so SAVE
for (j=1;j<=numQ;j++) {
var uAnswer = "#Answer_" + j.toString();
var uUserQid= "#UserQuestionId_" + j.toString();
var uQuestionId= "#QuestionId_" + j.toString();
var uUserId = "#UserId_" + j.toString();
var theUAnswer = $(uAnswer).val();
alert(theUAnswer );
var theuUserQuestionId = $(uUserQid).val();
alert(theuUserQuestionId );
var theuQuestionid = $(uQuestionId).val();
alert(theuQuestionid);
var theuUserId = $(uUserId).val();
alert(theuUserId );
$.ajax({
url: '/admin/savechallengequestion',
type: 'POST',
data: {
UserQuestionId: theuUserQuestionId.toString(),
LoginId: theuUserId.toString(),
QuestionId: theuQuestionid.toString(),
UserAnswer: theUAnswer.toString()
},
contentType: 'application/json; charset=utf-8',
//progress: showModSearchProgress(),
success: insSuccess(data),
error: function () {
alert("error");
}
});
}
}
My goal with this was to loop through the answers, sending one ajax call per transaction .If someone could tell me how to do this in one call I'm willing to listen :)
The alerts all pop, showing the proper data, but when I get to the ajax call, the progress function gets called, but the ajax call never makes it to the server - I never even see it in Fiddler - like nothing happened. The controller method and the model expected are listed below - havent filled out the controller method yet - still trying to get this to fire.
Model:
public class UserQuestionModelSave
{
public string UserQuestionId { get; set; }
public string LoginId { get; set; }
public string QuestionId { get; set; }
public string UserAnswer { get; set; }
}
Controller:
[HttpPost]
public ActionResult SaveChallengeQuestion(UserQuestionModelSave aQuestionInfo)
{
UserModelBuilder umb = new UserModelBuilder();
if (ModelState.IsValid)
{
try
{
return Json(new { success = true });
}
catch (Exception)
{
return Json(new { success = false });
}
}
return Json(new { success = false });
}
If anyone has any ideas I would greatly appreciate it - this has stumped me for almost 2 days now....
If ajax request doesn't fire, then you should check console for javascript errors. BTW, there is no "inSuccess()" function in your code, which you use in this ajax call.