Auto Complete in Razor MVC.NET [duplicate] - c#

I am using ASP.NET MVC3 with EF Code First. I have not worked previously with jQuery. I would like to add autocomplete capability to a dropdownlist that is bound to my model. The dropdownlist stores the ID, and displays the value.
So, how do I wire up the jQuery UI auto complete widget to display the value as the user is typing but store the ID?
I will need multiple auto complete dropdowns in one view too.
I saw this plugin: http://harvesthq.github.com/chosen/ but I am not sure I want to add more "stuff" to my project. Is there a way to do this with jQuery UI?

Update
I just posted a sample project showcasing the jQueryUI autocomplete on a textbox at GitHub
https://github.com/alfalfastrange/jQueryAutocompleteSample
I use it with regular MVC TextBox like
#Html.TextBoxFor(model => model.MainBranch, new {id = "SearchField", #class = "ui-widget TextField_220" })
Here's a clip of my Ajax call
It initially checks its internal cached for the item being searched for, if not found it fires off the Ajax request to my controller action to retrieve matching records
$("#SearchField").autocomplete({
source: function (request, response) {
var term = request.term;
if (term in entityCache) {
response(entityCache[term]);
return;
}
if (entitiesXhr != null) {
entitiesXhr.abort();
}
$.ajax({
url: actionUrl,
data: request,
type: "GET",
contentType: "application/json; charset=utf-8",
timeout: 10000,
dataType: "json",
success: function (data) {
entityCache[term] = term;
response($.map(data, function (item) {
return { label: item.SchoolName, value: item.EntityName, id: item.EntityID, code: item.EntityCode };
}));
}
});
},
minLength: 3,
select: function (event, result) {
var id = result.item.id;
var code = result.item.code;
getEntityXhr(id, code);
}
});
This isn't all the code but you should be able to see here how the cache is search, and then the Ajax call is made, and then what is done with the response. I have a select section so I can do something with the selected value

This is what I did FWIW.
$(document).ready(function () {
$('#CustomerByName').autocomplete(
{
source: function (request, response) {
$.ajax(
{
url: "/Cases/FindByName", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.CustomerName,
value: item.CustomerName,
id: item.CustomerID
}
})
);
},
});
},
select: function (event, ui) {
$('#CustomerID').val(ui.item.id);
},
minLength: 1
});
});
Works great!

I have seen this issue many times. You can see some of my code that works this out at cascading dropdown loses select items after post
also this link maybe helpful - http://geekswithblogs.net/ranganh/archive/2011/06/14/cascading-dropdownlist-in-asp.net-mvc-3-using-jquery.aspx

Related

How to refresh a particular division while using MVC

I have tried different ways to refresh a particular division in MVC.
1. Using HTML Action Link
2. Ajax Action Link
3. method
Please help me resolve this issue.
My Code is as follows:
<script src="~/scripts/jquery.unobtrusive-ajax.js"></script>
<script>
function updateAsyncCategoryUpdate() {
var url = '/Home/HomePage';
$.ajax({
url: url,
//data: { value: '1234' }, //if there are any parameters
dataType: "html", //or some other type
success: function () {
window.location.reload(true);
// or something in that area, maybe with the 'data'
},
error: function () {
//some derp
}
});
}
</script>`
#Ajax.ActionLink(item.Name, "HomePage", new { CATEGORy = item.Name }, new AjaxOptions {HttpMethod="GET", OnSuccess = "updateAsyncCategoryUpdate('item.Name')" })
You can append the success function.
This replaces content of div
success: function (data)
{
$('#divSelector').html(data);
}
This appends content of div
success: function (data)
{
$('#divSelector').append(data);
}
Your script function does not have parameter and you send Item.Name to it.(although you dont use this parameter inside the script!)
First, define parameter for updateAsyncCategoryUpdate function.
Secomd,Add a container element(like div) to your page with specific id(resultDiv for example) and replace the success code of your scrip with this:
success: function(result){
var myDiv = $('#resultDiv');
myDiv.empty();
myDiv.prepend(result);
}

Jquery UI AutoComplete not working with asp.net

This is my Jquery:
$("#completeMe").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Main.aspx/GetAutocomplete",
type: "POST",
dataType: "json",
data: Data,
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return { value: item };
}))
}
})
}
});
This is my Main.aspx.cs:
[System.Web.Services.WebMethod]
public static List<string> GetAutocomplete(string cityName)
{
List<string> City = new List<string>() { "hh", "hh1" };
return City;
}
Now this works when i return string instead of List. But when I use it like this with List I get:
Uncaught TypeError: undefined is not a function jquery-ui.min.js:9...
I don't understand, this solution seem to work to many people on web, maybe it has something to do with my jquery/ui versions? I am using jquery 1.7.1.min and jquery-ui latest version.
Change your success function like this
success: function (data) {
response($.map(data.d, function (item) {
return { value: item };
}))
Data is contained in data.d property.

Disable ASP:dropdownlist based on the selection of another ASP:Dropdownlist.value

I have two asp.net dropdownlists that I want to manipulate clientside with Javascript.
These two dropdowns are inside a modal open: function()
When dropdown1.value == "me"
I want dropdown2.value to be disabled
How can I accomplish this?
$(document).ready(function () {
if (document.getElementById('<%=dropdown1.ClientID%>').value == 'Me')
document.getElementById('<%=dropdown2.ClientID%>').disabled = true;
});
(optional) Part 2 I need to set an entity framework value to null after dropdown2 has been disabled how could I accomplish this without a postback?
Part 1:
$(document).ready(function ()
{
if($("#<%=dropdown1.ClientID%>").val() == "Me")
$("#<%=dropdown2.ClientID%>").prop("disabled",true);
});
Part 2 :
You would need to make an ajax call to a code behind or webservice to do that.
.ASPX
$.ajax({
type: "POST",
url: "PageName.aspx/CodeBehindMethodName",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
},
error: function (error) {
}
});
.ASPX.CS
[WebMethod]
public static void Test()
{
// Call EF code
}

Kendo UI Scheduler: Delete/Edit/Update only specified events

Im working with the Kendo Scheduler and users can create, delete, update, edit events to my local database. But I'm working with different users on this webapp so I only want those users to be able to edit, delete and update events that they personally created. So user 1 can delete events created by user 1 but can't delete events created by user 2 or 3 etc...
I thought I just modify the model/controller to check the userID of the logged in user against the userID in the db of the event.
public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
var userid = System.Convert.ToInt32(Session["userID"]);
if (ModelState.IsValid)
{
if (meeting.UserID== userid)
{
meetingService.Delete(meeting, ModelState);
}
else
{
"cant delete"
}
}
return Json(new[] { meeting });
}
But this doesn't seem to work, when click on delete the event dissapears but after reloading you see that it actually isn't really deleted from the db ... That of course isn't a good solution cause the goal is of course that that user just can't delete that event.
Any idea's?
VIEW
$(function () {
$("#scheduler").kendoScheduler({
date: new Date(Date.now()),
startTime: new Date(2013, 5, 13, 9, 0, 0, 0),
height: 800,
timezone: "Etc/UTC",
dataSource: {
transport: {
read: {
url: "#Url.Action("Meetings_Read", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
update: {
url: "#Url.Action("Meetings_Update", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
create: {
url: "#Url.Action("Meetings_Create", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
destroy: {
url: "#Url.Action("Meetings_Destroy", "Home")",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation === "read") {
var scheduler = $("#scheduler").data("kendoScheduler");
var result = {
start: scheduler.view().startDate(),
end: scheduler.view().endDate()
}
return kendo.stringify(result);
}
return kendo.stringify(options);
}
},
error: error_handler,
schema: {
model: {
id: "MeetingID",
fields: {
MeetingID: { type: "number" },
title: { from: "Title", type: "string", defaultValue: "No title", validation: { required: true } },
description: { from: "Description", type: "string" },
start: { from: "Start", type: "date" },
startTimezone: { from: "StartTimezone", type: "string" },
end: { from: "End", type: "date" },
endTimezone: { from: "EndTimezone", type: "string" },
recurrenceRule: { from: "RecurrenceRule", type: "string" },
recurrenceId: { from: "RecurrenceID", type: "number", defaultValue: null },
recurrenceException: { from: "RecurrenceException", type: "string" },
isAllDay: { from: "IsAllDay", type: "boolean" },
Timezone: { type: "string" },
RoomID: { type: "number", defaultValue: null },
Attendees: { type: "object" }
}
}
}
},
});
});
JAVASCRIPT
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.one("dataBinding", function (e) {
e.preventDefault();
for (var error in e.errors) {
alert("can't delete")
}
})
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
CONTROLLER
public virtual JsonResult Meetings_Destroy([DataSourceRequest] DataSourceRequest request, MeetingViewModel meeting)
{
if (ModelState.IsValid)
{
if(meeting.UserID == System.Convert.ToInt32(Session["userID"]))
{
meetingService.Delete(meeting, ModelState);
}
else
{
ModelState.AddModelError("","cant delete");
}
}
return Json(new[] { meeting });
}
I have a similar situation with my project where I have users that have limited access to do things on the calendar. I have found that you have to prevent things like Adds, Edits, and Deletes, that a user should not do, you can do this with the JavaScript events. Then, in the JavaScript functions, if a condiation is met (or not), then call the e.preventDefault(); method. Here's the demo on Client Events.
View (HTML 5 snippet)
remove: RemoveMe,
edit: EditMe,
add: AddMe,
View (MVC version snippet)
.Events(events =>
{
events.Add("AddMe").Edit("EditMe").Remove("RemoveMe");
})
JavaScript
function AddMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
function EditMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
function RemoveMe (e) {
if (SomeValue != SomeOtherValue)
e.preventDefault();
};
So, the good news is that this prevents the Calendar from showing updates (whether a Delete occurs or not), but it doesn't prevent the Delete Prompt (aka. "Are you sure you want to delete this event?"). Preventing the actions on the Client side is the way to go and you could extend it with alerts or notifications to the screen (since you would have the condition in the JavaScript function anyways), all to inform the user they can't do something.
ModelState.AddModelError("cant delete");
return Json(ModelState.ToDataSourceResult());
in the view
.Read("Grouping_Horizontal_Read", "Scheduler")
.Create("Grouping_Horizontal_Create", "Scheduler")
.Destroy("Grouping_Horizontal_Destroy", "Scheduler")
.Update("Grouping_Horizontal_Update", "Scheduler")
.Events(events => events.Error("error"))
.Events(events => events.Error("error")) is the trick and now importent the funktion for the error
function error(args) {
if (args.errors) {
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.one("dataBinding", function (e) {
e.preventDefault(); // cancel scheduler rebind if error occurs
for (var error in args.errors) {
alert(error + " args: " + args.errors[error].errors[0])
}
});
args.sender.cancelChanges();
}
}
It depends on how you are creating the meeting too.
Because to remove a task you just need a unique ID.
Right now it's just being deleted in JSON but not in the backend database, as I guess that meeting.id is not matching to the taskID generated when create event was fired.
I recommend to save taskID in ViewBag, SQL Table or somewhere, when task is created in the scheduler. Then pass this id as the parameter in your Meetings_Destroy method, when remove event is fired.
And [as mentioned in previous answer] use JavaScript remove event to validate logged in user, as e.preventDefault() can be used to restrict Meetings_Destroy method being fired if condition is not met. If debug is reached at Controller Method [Meetings_Destroy] it would remove event from scheduler [Either successfully removed in database or not], i-e from front end, but would bring it back on page refresh.
I have a same situation. I took a different approach to resolve it. In the edit function I compare task id and current userId and than I simply hide those button save, cancel and delete. These button will so only a user who created that.
function(e)
{
var customHide13= $(".k-scheduler-update, .k-scheduler-delete, .k-scheduler-cancel");
if (taskId == userId)
customHide13.show();
else
customHide13.hide();
},

asp.net mvc 3 highchart

In addition to my previous question, I tried to use the same working code (for MVC2) in a MVC3 project. I figured out it's not possible to use the jQuery.getJSON method. So I tried to use the $.post and $.ajax method instead, but again facing a problem.
In both methods I get an error "Jscript: JB is empty or not an object"
$.post("Home/GetLineData", null, function (items) {
var series = [];
jQuery.each(items, function (itemNo, item) {
//Get the items from the JSON and add then
//to the data array of the series
series.push({
name: item.Key,
data: item.Value
})
});
options.series = series;
chart = new Highcharts.Chart(options);
chart.render();
});
$.ajax({
type: "POST",
dataType: "json",
data: "{}",
contentType: "application/json; charset=utf-8",
url: "/Home/GetLineData",
cache: false,
succes: function (data) {
var series = [];
jQuery.each(data, function (itemNo, item) {
//Get the items from the JSON and add then
//to the data array of the series
series.push({
name: item.Key,
data: item.Value
})
});
options.series = series;
//Create the chart
chart = new Highcharts.Chart(options);
chart.render();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
Thanks in advance for helping me out (again :-s).
The problem was in the HTML, so the container element was not found.
So now both methods are working!
Jorelie.
BTW - you can use getJSON in MVC 3.0, but your controller method has to return the JSON object with a second parameter like so :
Json(result, JsonRequestBehavior.AllowGet);

Categories