autocomplete json - asp.net-mvc-3

i have follow the following wave for autocomplete and datepicker but the auto complete can't work Secondly is there any razor syntax to show the datepicker and autocomplete
javascriptfile
/// <reference path="jquery-1.5.1-vsdoc.js" />
/// <reference path="jquery-ui-1.8.11.js" />
$(document).ready(function () {
$(":input[data-autocomplete]").each(function () {
$(this).autocomplete({ source: $(this).attr("data-autocomplete") });
});
$(":input[data-datepicker]").datepicker();
})
The View File
#model TestDateTimePicker.Models.TestClass
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TestClass</legend>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
<input data-autocomplete="#Url.Action("AutoComplete", "City","City")" class="text-box single-line" id="City" name="City" type="text" value="" />
#Html.ValidationMessageFor(model => model.City)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Date)
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="The Date field is required." id="Date" name="Date" type="text" value="" data-datepicker="true"/>
#Html.ValidationMessageFor(model => model.Date)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
The Json Controller
public ActionResult AutoComplete(String s)
{
var d = db.Cities
.Where(r => r.Name.Contains(s))
.Select(r => new { label = r.Name });
return Json(d, JsonRequestBehavior.AllowGet);
}

#Url.Action("AutoComplete", "City", "City")
should be
#Url.Action("AutoComplete", "City")
The third argument that you are using represents route values which must be an anonymous object and not a string. As far as the autocomplete plugin is concerned, it uses the term query string when performing the AJAX request to fetch the data. So you will have to rename your controller action parameter as well:
public ActionResult AutoComplete(string term)
{
var d = db.Cities
.Where(r => r.Name.Contains(term))
.Select(r => new { label = r.Name });
return Json(d, JsonRequestBehavior.AllowGet);
}
Also make sure that that jquery-ui-1.8.11.min.js script is referenced in your page (cannot see it in your code example).
If it still doesn't work make sure that the AutoComplete action doesn't throw an exception when performing the query. Also look with FireBug or Developer Tools if there aren't some javascript errors and if the AJAX request is correctly sent.

The key to this solution is: We need to use item.label name because the AJAX will return the value in list format so we need to extract the value as shown in the below example.
<html>
<head>
<title>Ajax</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function() {
$("#myname").autocomplete({
source: 'emp.php',
select: function (event, ui) {
$("#myname").val(ui.item.label);
$("#myid").val(ui.item.id);
},
minLength: 0,
autoFocus: true,
});
});
</script>
</head>
<body>
<h2>Ajax Testing</h2>
<input name="myname" id="myname" type="text">
<input name="myid" id="myid" type="text">
</body>
</html>
-------------- Below is the code of PHP for emp.php page --------------------------
<?php
require_once 'connection.php';
$query = "SELECT myname as label , myid as id FROM emp WHERE name LIKE ? ORDER BY name";
$rsTable = sqlsrv_query($conn, $query,array('%'.$_REQUEST['term'].'%'));
while ($row_rsTable = sqlsrv_fetch_array($rsTable, SQLSRV_FETCH_ASSOC)) {
$emparray[] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $row_rsTable);
}
echo json_encode($emparray);
sqlsrv_close($conn);
?>

Related

CheckedNodes posted is always null

I have followed the tutorial and the documentation of kendo treeview but I have an instance where in I added hidden values into the checkbox template. The problem is when the submit button was clicked, the posted values is always null.
Here is my view
#using (Ajax.BeginForm("Projects", "Maintenance", FormMethod.Post,null))
{
<div class="treeview-back">
#Html.TextBoxFor(c => c.UserAccountID)
#(Html.Kendo().TreeView()
.Name("treeviewSiteList")
.DataTextField("Name")
.Checkboxes(checkboxes => checkboxes
.CheckChildren(true)
.TemplateId("treeview-checkbox-template")
)
.DataSource(dataSource => dataSource
.Read(read => read
.Action("UserProjectFolderList", "Maintenance", new { useraccount_id = Model.UserAccountID }))
)
)
</div>
<button type="submit" class="k-button">Save</button>
}
<script id="treeview-checkbox-template" type="text/kendo-ui-template">
<input type="checkbox" name="treeviewNodes[#= item.id#]" value="#= item.id # "/>
<input type="hidden" name="treeviewNodes[#= item.id #]" value="#= item.SiteID #"/>
</script>
Here is my view:
public ActionResult GetChecked(int[] treeViewNodes)
{
}

MVC3 custom server-side data annotation validation not working in partial view

I am trying to add custom data validation via data annotations. I am only concerned about server-side validation at this point. Everything I have seen here and elsewhere references client-side validation. I've stripped down all my code, ran a few test cases and I can get this working just fine on a regular view but as soon as the form is in a partial view, the code no longer breaks in the method to override IsValid.
In either case I can see the custom attribute being initialized. When the form is in a regular view I can see the override method being executed upon submitting the form, but when in a partial view the code never gets executed and it goes right to the HttpPost action.
I have spent the better parts of two days trying to figure this out and am at a loss. Any help would be GREATLY appreciated.
Note:
The code below does return the same view when it enters the HttpPost action. I have it like this for testing purposes. I know my override is never getting called from the partial view and thus IsValid is always true.
View showing form where the validation works
#model eRecruitBoard.ViewModels.HomeIndexViewModel
#{
ViewBag.Title = "eRecruitBoard";
}
#*<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>*#
<h2>Login/homepage</h2>
<br /><br />
<div class="errorMessage">
#Html.DisplayFor(m => m.LoginErrorMsg)
</div>
<br />
#using (Html.BeginForm("Index", "Home")) {
<div id="loginControlBox">
<fieldset>
<legend>Welcome to eRecruitBoard</legend>
<div class="editor-label">
#Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="editor-label">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
<div class="editor-label">
#Html.EditorFor(m => m.Date)
#Html.ValidationMessageFor(m => m.Date)
</div>
<p>
<input type="submit" value="Log In" />
</p>
</fieldset>
</div>
}
<div>
#Html.Action("BlankForm", "TestForm")
</div>
Partial View (these script calls also come in via _Layout, but I had them here for testing as well)
#model eRecruitBoard.ViewModels.TestFormViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcValidation.js")" type="text/javascript"></script>
#using (Html.BeginForm("NewActivity2", "TestForm", FormMethod.Post))
{
<fieldset>
<legend>Test Form</legend>
<br />
#Html.LabelFor(m => m.Date)
#Html.EditorFor(m => m.Date)
#Html.ValidationMessageFor(m => m.Date)
<input id="activityTimelineSubmit" type="submit" value="Submit" />
</fieldset>
}
ViewModel (for partial view)
namespace eRecruitBoard.ViewModels
{
public class TestFormViewModel
{
[Required]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
[NonFutureDate()]
[Display(Name = "Date")]
public DateTime Date { get; set; }
}
}
Controller (for partial view)
namespace eRecruitBoard.Controllers
{
public class TestFormController :BaseController
{
public ActionResult BlankForm()
{
var viewModel = new TestFormViewModel
{
Date = DateTime.Today
};
return PartialView("_TestForm", viewModel);
}
[HttpPost]
public ActionResult NewActivity2(DateTime Date)
{
if (!ModelState.IsValid)
return RedirectToAction("Index", "Home");
else
return RedirectToAction("Index", "Home");
}
}
}
Validation code
using System;
using System.ComponentModel.DataAnnotations;
namespace eRecruitBoard.WebLibrary.Validation
{
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public class NonFutureDateAttribute : ValidationAttribute //public sealed class
{
public NonFutureDateAttribute(): base("Activity can only be saved for today or dates in the past.")
{
}
public override bool IsValid(object value)
{
DateTime dateToCheck = (DateTime)value;
return (dateToCheck <= DateTime.Today);
}
}
}
If you RedirectToAction you lose all validation. You have to return PartialView(model) in your POST action. That would require changing the parameter type of NewActivity2 to TestFormViewModel instead of DateTime.
Update your code with example of how you display the partial view (#Html.Partial() or javascript) if it still doesnt work.

Call ActionResult from Ajax.BeginForm

I using Ajax begin form and when I click submit button, post method doesn't call, here is code:
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "personListDivforReturnPerson"}))
{
<div class="ReturnPersonGeneralPageBody">
<div class="returnPersonHeader">
საზღვრის კვეთისას დაფიქსირებული მონაცემები
</div>
<div class="fieldNameForMIA">
<span>#Html.LabelFor(model => model.LastName, "გვარი")
<br />
#Html.EditorFor(model => model.LastName)
</span>
<div class="fieldNameInnerForMIA">
<span>#Html.LabelFor(model => model.FirstName, "სახელი")
<br />
#Html.EditorFor(model => model.FirstName)
</span>
</div>
</div>
<div class="fieldNameForMIA">
<span>#Html.LabelFor(model => model.PersonalNo, "პირადი ნომერი")
<br />
#Html.EditorFor(model => model.PersonalNo)
</span>
<div class="fieldNameInnerForMIA">
<span>#Html.LabelFor(model => model.DateOfBirth, "დაბადების თარიღი")
<br />
#Html.EditorFor(model => model.DateOfBirth)
</span>
</div>
</div>
<div class="fieldNameForReturnCheckBox">
#Html.LabelFor(model => model.IsIdentified, "სხვა სახელით დაბრუნდა")
#Html.CheckBoxFor(model => model.IsIdentified)
</div>
<div class="saveReturnPerson">
<input type="image" name="submit" id="submit" src="/Content/Resources/SaveGeo.gif" />
</div>
</div>
}
and here is post method which is never called:
[HttpPost]
public ActionResult EditReturnPerson(int id, FormCollection collection)
{ ....
but this method is called when first is loaded:
public ActionResult EditReturnPerson(long parentObjectId, int parentObjectTypeId, bool readOnly = false)
{
....
Mention the method as POST in AjaxOptions
new AjaxOptions { UpdateTargetId = "personListDivforReturnPerson",
HttpMethod ="POST"}
If you do not mention, It will take the Default which is GET.
EDIT : Also If you want to handle it with your own code, You can do it with handwritten JavaScript. Pretty clean and full control.
Get rid of the AjaxBeginForm and use a normal form in your view.
#using(Html.BeginForm())
{
#Html.EditorFor(model => model.FirstName)
#Html.EditorFor(model => model.PersonalNo)
<input type="submit" class="ajaxSubmit" />
}
Now have some javascript to handle the form submit
<script type="text/javascript">
$(function(){
$(".ajaxSubmit").click(function(e){
e.preventDefault();
var item=$(this);
$.post("#Url.Action("EditReturnPerson","YourControllerName")",
item.closest("form").serialize(), function(response){
$("#personListDivforReturnPerson").html(response);
});
});
});
</script>
ბიჭო აქ ვერ გეტყვიან ვერაფერს :D გეუბნები სერვერს მიმართავს და იქ უშლის რაღაცა ხელს. კლიენტის მხარეს ყველაფერი კარგადაა. ეს კიდე მაგარი კაცია, ფორმას უკეთებ სუბმით-ს და default მეთოდი არის პოსტი მაგ დროს.
I found my problem, the problem was [HttpPost] public ActionResult EditReturnPerson(int id, FormCollection collection) { .... in this part, id was int and my id in DB was bigint, so I changed int to long in controller and everything worked, thanks for advice.

pass a value of the form from view to controller

how do i pass the value of the form, which is (i assume) a string of date to the controller...
here is my view:
<script type="text/javascript" language="javascript">
$(function () {
$(".datepicker").datepicker({ onSelect: function (dateText, inst) { $("FORM").submit(); },
altField: ".alternate"
});
});
</script>
#model IEnumerable<CorReservation.Models.Reservation>
#{
ViewBag.Title = "Index";
}
<div class="divRightSide">
<div>
<div class="datepicker">
</div>
<form action="/" title="fff">
<input type="text" class="alternate" readonly="readonly" />
</form>
</div>
// do something eg. foreach (var item in Model)
{ #Html.DisplayFor(modelItem => item.Date)}
here is my controller: i want to pass the date selected from the datepicker to the controller and then the controller would return an Ienumerable of reservations...
DateTime date = System.DateTime.Now;
private ReservationEntities db = new ReservationEntities();
public ViewResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string dateInput)
{
date = Convert.ToDateTime(dateInput);
var reservations = db.Reservations.Where(r=> r.Date ==date).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
return View(reservations);
}
There are 2 ways to do this. Make the form input name attribute match the expected attribute in your controller.
For example:
<input type="text" class="alternate" readonly="readonly" name="dateInput" />
Or if there's going to be a lot of input values, use a Model.
It's automatically done based on the 'name' attribute of the HTML fields you want to submit.
Change your form to
<form action="/" title="fff">
<input name="dateInput" type="text" class="alternate" readonly="readonly" />
</form>
And it should work just like that.
Also, as you are using Razor syntax, you could use the Razor HTML helpers like so
#model IEnumerable<CorReservation.Models.Reservation>
#{
ViewBag.Title = "Index";
}
<div class="divRightSide">
<div>
<div class="datepicker">
</div>
#using(#Html.BeginForm("<your controller name>", "<your action name e.g. Index>"){
Html.TextBox("dateInput", "", new { #readonly="readonly", #class="alternate" })
}
</div>
// do something eg. foreach (var item in Model)
{ #Html.DisplayFor(modelItem => item.Date)}

How i can submit multiple objects inside the form post values to be added

i have a create view to add answers to a question, currently the user can only add one answer at the same time when he clicks on the submit button, instead of this i want the user to be able to insert multiple answers objects into the same view and then the system to add all these new answer objects to the database after the user click on the submit button, my current view looks as the follow:-
#model Elearning.Models.Answer
#{
ViewBag.Title = "Create";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id = "remove">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "remove"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
and the action methods look as the follow:-
public ActionResult Create(int questionid)//, int assessmentid)
{
ViewBag.questionid = questionid;
Answer answer = new Answer();
return PartialView("_answer",answer);
}
//
// POST: /Answer/Create
[HttpPost]
public ActionResult Create(int questionid, Answer a)
{
if (ModelState.IsValid)
{
repository.AddAnswer(a);
repository.Save();
return PartialView("_details",a);
}
return View(a);}
so how i can modify the above code to be able to insert multiple answer objects at the same view and then submit these answers objects at the same time when the user click on the submit button?
Try Post a List
Add input by javascript when user click "Add Answer".
And when submit the form ,it will post all answer data to binding to List
<script>
$(document).ready(function () {
var anwserCount = 1;
$("#addbutton").click(function () {
$("#AnwsersDiv")
.append("<input type='text' name='Anwsers[" + anwserCount + "]'/>");
anwserCount += 1;
});
});
</script>
#using (Html.BeginForm())
{
<div id="AnwsersDiv">
<input type="text" name="Anwsers[0]" />
</div>
<input id="addbutton" type="button" value="Add answer" />
<input type="submit" value="submit" />
}
Model
public class Answer
{
public List<String> Anwsers { get; set; }
}
When submit the form
I think this is what you are looking for
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Conclusion: you should make the post action with ICollection<Answer> Parameter, then it will be easy to get them when you post your main form, and create the appropriate QUESTION object, then save them all with only one submit.

Resources