I have a problem in How to use javascript variables in C# and vise versa : I have this Model passing to the view:
public List<Tache> Get_List_Tache()
{
Equipe _equipe = new Equipe();
List<Tache> liste_initiale = _equipe.Get_List_tache();
return liste_initiale;
}
It's a list of objects Tache in which I'd like to use it's three fields Tache_description, Begin_date and End_date.
In my JavaScript code I have this function and it works fine:
<script>
$(document).ready(function () {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
theme: true,
header: {left: 'prev,next today',center: 'title',right: 'month,agendaWeek,agendaDay'},
editable: true,
events: [
#foreach (var m in Model.Get_List_Tache())
{
#:{title : #m.Tache_description , start: #m.Begin_date , end : #m.Begin_date }
}
]
});
});
</script>
The values of the array events are just for test, and I need to fill events by the value of the Model. For each element like this: title = Tache_description, start = Begin_date and end = End_date.
So how can I do this task? Any suggestions?
Try this,
foreach (var item in YourList)
{
events: [{ title: '#item.title', start: '#item.start', end: '#item.end'}]
}
So, in this code just replace name your model entity.
Make a foreach razor loop within javascript :
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
theme: true,
header: {left: 'prev,next today',center: 'title',right: 'month,agendaWeek,agendaDay'},
editable: true,
events: [
#
{
bool isFirst = true;
}
#foreach(var m in Model)
{
if(!isFirst)
{
#:,
}
#:{title: #m.Tache_description, ...<other properties here>}
isFirst = false;
}
]
});
For title, you can do title = "#Tache_description"
Not sure about the format/type of your Begin_date and End_date, you may need some function to read the date into a javascript format. Shouldnt be that hard.
Loop through each element and add the elements to the events array. It is something like...
events = new Array()
#foreach(tache in list){
item = { blah : blah, blah : blah };
events.push(item);
}
for each c# item in this c# list, write these lines of javascript. You may end up with a very long javascript code block, but it should do the trick. Above is pseudocode.
To add to Darin's answer: If you need the server-side variables in an external JavaScript file, take a look this blog post: Generating External JavaScript Files Using Partial Razor Views
1: if your model is expecting the list of Tache then you have the whole list you can manipulate.
2: you can get the data using jquery ajax as json data by calling your action Get_List_Tache().
Assuming this javascript is inline in your page you could do the following:
#model IList<Tache>
<script type="text/javascript">
var events = #Html.Raw(Json.Encode(Model.Select(x => new { title = x.Description, start = x.Begin.ToString("o"), end = x.End.ToString("o") })));
$('#calendar').fullCalendar({
theme: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
events: events
});
</script>
This example assumes that your Tache model has properties Description, Begin and End:
public class Tache
{
public string Description { get; set; }
public DateTime Begin { get; set; }
public DateTime End { get; set; }
}
And if this script is in a separate javascript file you could still set a global events variable in your view which will later be used by your script. Alternatively you could fetch this model using an AJAX call.
Related
// Kendo table sortable
var kendoSortable = grid.table.kendoSortable({
filter: ">tbody >tr",
hint: function (element) { // Customize the hint.
var table = $('<table style="width: 600px;" class="k-grid k-widget"></table>'),
hint;
table.append(element.clone()); // Append the dragged element.
table.css("opacity", 0.7);
return table; // Return the hint element.
},
cursor: "move",
placeholder: function (element) {
return $('<tr colspan="4" class="placeholder"></tr>');
},
change: function (e) {
var skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
}
});
Im trying to save the order after dragging and reordering. to the database so that when i reload the page the order where i have ordered it would be the exact order when i am reaordering it
Look into using the change event for the Sortable widget. This event provides the oldIndex and newIndex positions for the item that was moved.
Below is an example of one way to go about getting the reordered items and then sending that data to the server to save the changes. Hopefully, this will help you get started with solving your problem.
The change event firing indicates the item has been sorted and the item's position has changed in the DOM. Looking at the change event below, I'm getting the data items for the current page of the grid into currentGridView. Then I'm using the slice() method to get the items between the oldIndex and newIndex. Then I call the updateSequence function.
The updateSequence function creates an array to store objects to be passed to the server. These objects are based on the DataSequenceModel class. Basically, I just need to know the Id and the new sequence for each item that has been reordered. After this I'm using a basic Ajax POST to send the data to the server.
Index.cshtml - Here is a dojo based on Telerik's Integration - Grid demo and updated with my changes.
<div id="grid"></div>
<script>
$(document).ready(function () {
var grid = $("#grid").kendoGrid({
// ...Basic grid setup
}).data("kendoGrid");
grid.table.kendoSortable({
filter: ">tbody >tr",
hint: $.noop,
cursor: "move",
placeholder: function(element) {
return element.clone().addClass("k-state-hover").css("opacity", 0.65);
},
container: "#grid tbody",
change: function (e) {
// Get the indexes and data items that have been reordered.
var skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip;
var currentGridView = grid.dataSource.view();
var dataChanged = currentGridView.slice(oldIndex, newIndex + 1);
updateSequence(oldIndex, dataChanged);
}
});
});
function updateSequence(startIndex, dataChanged) {
// Create array to be passed to Controller. Based on DataSequenceModel class.
let data = [];
let newSequence = startIndex;
for (var i = 0; i < dataChanged.length; i++) {
data.push({ Id: dataChanged[i].ProductID, NewSequence: newSequence });
newSequence++
}
$.ajax({
type: "POST",
url: 'https://localhost:44395/Test/UpdateSequence',
contentType: 'application/json',
data: JSON.stringify(data),
success: function (data) {
console.log(data);
},
error: function (e) {
console.error(e);
}
});
};
</script>
TestController.cs
public class TestController : Controller
{
public ActionResult Index()
{
return View();
}
public bool UpdateSequence(IEnumerable<DataSequenceModel> data)
{
// ...Logic to update sequence in database.
return true;
}
}
DataSequenceModel.cs
public class DataSequenceModel
{
public int Id { get; set; }
public int NewSequence { get; set; }
}
I have this FullCalendar portion of code on my page to pull events from an API controller in a Razor Pages project:
var calendar;
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['dayGrid', 'interaction', 'list', 'timeGrid'],
defaultView: 'dayGridMonth',
customButtons: {
newEventButton: {
text: 'new event',
click: function () {
window.location.assign("Calendars/EditPersonnelEvent/0");
}
}
},
header: {
left: 'prev,next today',
center: 'title',
right: 'newEventButton,dayGridMonth,timeGridWeek,timeGridDay'
},
events: "/api/fetchEvents"
});
calendar.render();
})
and it seems to be working just fine, here's the snip of the fetch:
The problem is, the event fetched doesn't show on the calendar, on any of the views. When I paste that JSON into a hard-coded event, it works fine and I see the event, just not when it's from the GET. I've tried this with eventSources to no avail. I've searched about 30 different answers here and still no luck. The JSON seems to be formatted correctly, it seems to be getting fetched correctly, it's just not showing up. And yes, I'm looking at the correct days ;)
REQUESTED UPDATE:
Here is the "response" data:
and here's the .NET code for this fetch:
[Route("api/fetchEvents")]
[ApiController]
public class FetchEventsController : ControllerBase
{
private readonly IPersonnelEventService _personnelEventService;
public FetchEventsController(IPersonnelEventService personnelEventService)
{
_personnelEventService = personnelEventService;
}
// GET: api/FetchEvents/5
[HttpGet]
public string Get(string start, string end)
{
int currentUserId = User.Identity.GetUserId();
DateTime objStart = DateTime.Parse(start, null, System.Globalization.DateTimeStyles.RoundtripKind);
DateTime objEnd = DateTime.Parse(end, null, System.Globalization.DateTimeStyles.RoundtripKind);
List<Entities.PersonnelEvent> events = new List<Entities.PersonnelEvent>(_personnelEventService.GetPersonnelEventsByUserId(currentUserId, objStart, objEnd));
return JsonConvert.SerializeObject(events.Select(pe => pe.GetEventAsFullCalendarJson()).ToList());
}
}
and here's the code for "GetEventAsFullCalendarJson":
public string GetEventAsFullCalendarJson()
{
var info = new
{
title = Name,
start = StartDate,
end = EndDate
};
return JsonConvert.SerializeObject(info);
}
}
The problem is you are double-serializing your data.
You serialise each event object individually in GetEventAsFullCalendarJson() when you do return JsonConvert.SerializeObject(info);. So at that point you already have a JSON string representing a single event.
But then you combine all these together and serialise the whole thing again when you write return JsonConvert.SerializeObject(events.Select(pe => pe.GetEventAsFullCalendarJson()).ToList()); in the Get() method. This means the already-serialised JSON event strings are serialised again - which is why you've got quote marks round the event object (e.g. "{ ... }" and then escaped quotemarks (\") within it.
The outcome is that to fullCalendar, your data just looks like an array of strings, not an array of event objects.
The fix is simple - remove the serialisation of the individual events. An object/array must be serialised all at once to create a coherent single piece of JSON.
This:
return JsonConvert.SerializeObject(events.Select(pe => {
title = pe.Name,
start = pe.StartDate,
end = pe.EndDate
}).ToList());
would work, I think.
I am trying to implement json feeds FullCalendar.
If I use a signature for GetCalendarEvents with no arguments, the View calls the function. If I use it with the start and end arguments, the function does not get called. The only thing different that I can find in my code appreciable to the code in the sample is that they somehow get away with calling the script in the view without the header information I have to put in.
Header Code in View
<link rel='stylesheet' href='~/Content/fullcalendar.css' />
<link rel='stylesheet' href='~/Content/scheduler.css' />
<script src='~/Scripts/jquery-2.2.0.js'></script>
<script src='~/Scripts/moment.min.js'></script>
<script src='~/Scripts/fullcalendar.js'></script>
<script src='~/Scripts/moment.js'></script>
<script src='~/Scripts/scheduler.js'></script>
This works fine in example code I downloaded from here.
http://www.codeproject.com/Articles/638674/Full-calendar-A-complete-web-diary-system-for-jQue
The following is the code in question.
View Code
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'agendaDay',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
events: '/Calendar/GetCalendarEvents/'
});
Controller Code
public JsonResult GetCalendarEvents(double start, double end)
//public JsonResult GetCalendarEvents()
{
var fromDate = CalendarEvent.ConvertFromUnixTimestamp(start);
var toDate = CalendarEvent.ConvertFromUnixTimestamp(end);
var rslt = _orderService.Query(s => s.FromDate >= fromDate && s.ToDate <= toDate);
List<CalendarEvent> result = new List<CalendarEvent>();
CalendarEvent rec = new CalendarEvent();
rec.ID = "lskfj1231";
rec.title = "Testing";
rec.start = "2016-01-17T12:00:00Z";
rec.end = "2016-01-17T13:00:00Z";
result.Add(rec);
var eventList = from e in result
select new
{
id = e.ID,
title = e.title,
start = e.start,
end = e.end
};
var rows = eventList.ToArray();
return Json(rows, JsonRequestBehavior.AllowGet);
}
I sorted it out. For reasons unknown (I will look into this at some point and update this solution) the sample project/solution sends a request to the controller for start and end arguments in unix time format. My project/solution sends the request to the controller for start and end arguments in DateTime format.
I just modified my signature in the Calendar controller for GetCalendarEvents(DateTime start, DateTime end) and everything is great.
Thanks!
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
data : {start : 11, end : 15}
defaultView: 'agendaDay',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
events: '/Calendar/GetCalendarEvents/'
});
You need to pass attributes in the data parameter
You can use it by two ways.
1) Event as a json feed
eventSources: [
// your event source
{
url: '/Calendar/GetCalendarEvents/',
type: 'GET',
data: {
start: startDate,
end: endDate
},
error: function() {
alert('there was an error while fetching events!');
}
}
]
2) Event as a function
events: function(start, end, timezone, callback) {
$.ajax({
url: '/Calendar/GetCalendarEvents/',
data: {
// our hypothetical feed requires UNIX timestamps
start: start.unix(),
end: end.unix()
},
success: function(events) {
callback(events);
}
});
}
In the example code that you downloaded this is handled in the fullcalendar.js file. Take a look the _fetchEventSource method() at line 984.
I think that this is where the dates are added into the controller method call. You could trace your code to see if it is running through the js file, but my guess is that you don't have this file included in the correct order so it isn't utilizing the methods in the fullcalendar.js file.
I'm developing a web application with Telerik Kendo in Razor. Here is my problem:
I have a variable that I set as a type List<class>.
#{
ViewBag.Title = "Home Page";
var dpdminst = new DB();
var data = dpdminst.getdata();}
I want to be able to use this variable (data) to set my DataSource in my Javascript:
<script>
var displaydata = #data
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
columns:["amount"]
}
});
});
</script>
Does anyone know if this can be done?
Here is my JsonResult:
public JsonResult GetJsonData()
{
var DBinst = new DB();
var TradeData = DBinst.tradedata();
var json = JsonConvert.SerializeObject(TradeData);
var result = new JsonResult()
{
Data = json
};
return result;
}
Have an action method which returns the data you want in JSON format. in your document.ready event, make an ajax call to get this data and then you can set it as your data source.
public ActionResult GetJsonData()
{
var dpdminst = new DB();
var data = dpdminst.getdata();
return Json(data,JsonRequestBehaviour.AllowGet);
}
and in your view use the getJSON method to get data from this action method and use that as needed. You may format the incoming json as per your UI requirements
$(document).ready(function () {
$.getJSON("#Url.Action("GetJsonData","YourControllerName")",function(data){
// you have your json data in the "data" variable.
// now you may use it to set the data source of your grid library
});
});
If you dont want to deal with ajax/json, then I would try to achieve what you want as follows:
<script>
var displaydata = [
#foreach (var record in dpdminst.getdata())
{
#: { amount: '#record' },
}
];
$(document).ready(function () {
$("#grid").kendoGrid({
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
dataSource: {
data:displaydata,
schema: {
model: {
fields: {
amount: { type: "string" },
}
}
},
},
columns:["amount"]
});
});
</script>
Also please notice that you had columns:["amount"] in a wrong place, also this code has to be in your cshtml for razor syntax to work properly.
I am trying to build an autocomplete, but I have troubles patching along the parts.
First, my view include this field:
<p>#Html.TextBoxFor(_item => _item.mCardName, Model.mCardName, new { #class = "cardText", id = "card_name"} ) </p>
Very simple. Next, the javascript call:
<script type="text/javascript">
$(function() {
$('#card_name').autocomplete({
minlength: 5,
source: "#Url.Action("ListNames", "Card")",
select: function (event, ui) {
$('#card_name').text(ui.item.value);
},
});
});
</script>
Which calls this method:
public ActionResult ListNames(string _term)
{
using (BlueBerry_MTGEntities db = new BlueBerry_MTGEntities())
{
db.Database.Connection.Open();
var results = (from c in db.CARD
where c.CARD_NAME.ToLower().StartsWith(_term.ToLower())
select new {c.CARD_NAME}).Distinct().ToList();
JsonResult result = Json(results.ToList(), JsonRequestBehavior.AllowGet);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
If i insert the "Power" word, the JSON data is posted back like this:
{"ContentEncoding":null,"ContentType":null,"Data":[{"CARD_NAME":"Power Armor"},{"CARD_NAME":"Power Armor (Foil)"},{"CARD_NAME":"Power Artifact"},{"CARD_NAME":"Power Conduit"},{"CARD_NAME":"Power Conduit (Foil)"},{"CARD_NAME":"Power Leak"},{"CARD_NAME":"Power Matrix"},{"CARD_NAME":"Power Matrix (Foil)"},{"CARD_NAME":"Power of Fire"},{"CARD_NAME":"Power of Fire (Foil)"},{"CARD_NAME":"Power Sink"},{"CARD_NAME":"Power Sink (Foil)"},{"CARD_NAME":"Power Surge"},{"CARD_NAME":"Power Taint"},{"CARD_NAME":"Powerleech"},{"CARD_NAME":"Powerstone Minefield"},{"CARD_NAME":"Powerstone Minefield (Foil)"}],"JsonRequestBehavior":0,"MaxJsonLength":null,"RecursionLimit":null}
For reference purpose, here are two of the scripts that run:
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
However nothing is displayed. I would have liked to see the results displayed like a normal autocomplete would do. Can anyone help me out making things work?
EDIT
I have been working on this for a while. I have posted up there the new javascript, controller method and results obtained. But the thing still does not work and I would appreciate any help.
for autocompletes, i use the javascriptserializer class. the code goes something like this.
My.Response.ContentType = "application/json"
Dim serializer As JavaScriptSerializer = New JavaScriptSerializer
Dim dt As DataTable = GetDataTable("proc_name", My.Request.QueryString("term"))
Dim orgArray As ArrayList = New ArrayList
For Each row As DataRow In dt.Rows
Dim thisorg As New thisOrg
thisorg.id = row("organization_child_id")
thisorg.value = row("organization_name")
orgArray.Add(thisorg)
Next
My.Response.Write(serializer.Serialize(orgArray))
Public Class thisOrg
Public id As Integer
Public value As String
End Class
basically just takes a datatable, adds a series of objects to the array, then serializes it.
Finally! After taking a break, I got my answer.
See this?
public ActionResult ListNames(string _term)
{
using (BlueBerry_MTGEntities db = new BlueBerry_MTGEntities())
{
db.Database.Connection.Open();
var results = (from c in db.CARD
where c.CARD_NAME.ToLower().StartsWith(_term.ToLower())
select new {c.CARD_NAME}).Distinct().ToList();
JsonResult result = Json(results.ToList(), JsonRequestBehavior.AllowGet);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
As it happens, I was building a Json object OF another Json object. So that's why the data was not passed properly.
I've rebuilt the method, made it work, and refined it like this:
public JsonResult ListCardNames(string term)
{
using (BlueBerry_MagicEntities db = new BlueBerry_MagicEntities())
{
db.Database.Connection.Open();
var results = from cards in db.V_ITEM_LISTING
where cards.CARD_NAME.ToLower().StartsWith(term.ToLower())
select cards.CARD_NAME + " - " + cards.CARD_SET_NAME;
JsonResult result = Json(results.ToList(), JsonRequestBehavior.AllowGet);
return result;
}
And my javascript action:
<script type="text/javascript">
$(function() {
$('#searchBox').autocomplete({
source: function(request, response) {
$.ajax({
url: "#Url.Action("ListCardNames")",
type: "GET",
dataType: "json",
data: { term: request.term },
success: function(data) {
response($.map(data, function(item) {
return { label: item, value1: item };
}));
}
});
},
select:
function(event, ui) {
$('#searchBox').val(ui.item);
$('#cardNameValue').val(ui.item);
return false;
},
minLength: 4
});
});
</script>
And now everything works like a charm.