using datepicker('refresh') on ajax success and inline datepicker's beforeShowDay? - javascript

I'm using jquery and jquery ui 1.8.7. I'm creating an inline datepicker when the page loads, then in my ajax success function, I'm calling $('#mydiv').datepicker('refresh'); (I'll post code below).
If the data has been returned from ajax (eg. on the refresh), beforeShowDay calls the highlightDays() function. I know that I'm hitting highlightDays with the correct data twice before everything crashes to a halt and I get an error "TypeError: Cannot read property 0 of undefined".
It seems like the events array is being destroyed after a certain amount of time, but I don't know enough about ajax to really say what's happening. Can anyone point me in the right direction to fix this?
function highlightDays(date) {
var day = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
console.log(typeof(events)); // This will return as an object twice before throwing an the above mentioned error
if($.inArray(day, events) !== -1) {
return new Array(true, '');
} else {
return new Array(false, '');
}
}
function getEventData() {
return $.ajax({
url: Drupal.settings.basePath + 'correct_path',
data: search+'&path='+window.location.pathname,
dataType: 'json',
type: 'POST',
success: function(data, textStatus, jqXHR) {
// save our returned data
events = new Object();
events = data;
$('#mydiv').datepicker("refresh");
}
});
}
function createDatepicker() {
// Attach datepicker to the parent div so it returns as
// inline.
$('#mydiv').datepicker({
dateFormat: 'yy-mm-dd',
speed: 'immediate',
altField: '#edit-date-filter-value-datepicker-popup-1',
beforeShowDay: function(date) {
if(typeof (_event_days) === 'undefined') {
return new Array(true, '');
} else {
highlightDays(date);
}
},
});
$('#myinput').hide();
}
getEventData();
createDatepicker();

The following code is what ended up working for me. Two big differences. Reworking the highlightDays function and adding all data returned from the ajax call to a global events array, to be used later in highlightDays.
var events = [];
function highlightDays(date) {
var dayClass = [true, ''];
var date = $.datepicker.formatDate('yy-mm-dd', new Date(date));
$.each(events, function(key, value) {
if (date === value[0]) {
dayClass = [true, "ui-state-highlight"];
return dayClass;
} else {
return dayClass;
}
});
return dayClass;
}
function getEventData() {
return $.ajax({
url: 'myurl',
data: search+'&path='+window.location.pathname,
dataType: 'json',
type: 'POST',
success: function(data, textStatus, jqXHR) {
$.each(data, function (index, value) {
events.push([value]);
});
// popup is the date input field
// attaching datepicker to the parent div makes
// it an inline picker
popup.parent().datepicker('refresh');
}
});
}
function createDatepicker() {
popup.parent().datepicker({
dateFormat: 'yy-mm-dd',
beforeShowDay: highlightDays
});
popup.hide();
}
function getSearchString() {
// Return a search string to pass to the ajax call
var search = window.location.search;
if(search !== '') {
while(search.charAt(0) === '?') {
// remove the leading question mark in the search string
search = search.substr(1);
}
}
return search;
}
// If our popup selector exists, create the datepicker and get event data
if (popup.length) {
var search = getSearchString();
getEventData();
createDatepicker();
}

Related

Call ViewBag in Jquery to get the value from controller

I am calling ViewBag.DeliveryDatebySupplier to update my textbox or just to alert. The value was always null. But when I debug and check the ViewBag in controller it has the date value.
Controller
if (ds.Tables[0].Rows.Count == 1)
{
string dt = ds.Tables[0].Rows[0]["DeliveryDt"].ToString();
DateTime myDate = Convert.ToDateTime(dt);
dt = myDate.ToString("yyyy-MM-dd");
ViewBag.DeliveryDatebySupplier = dt.ToString();
//Session["NewDeliveryDate"] = dt.ToString();
}
Jquery
function getDeliveryDateBySupplier() {
var _storeID = $('#ddlStoreID :selected').val();
var _SupplierID = $('#ddlSupplier :selected').val();
var url = "#Url.Content("~/Home/DeliveryDatebySupplier")";
$.ajax({
data: {
StoreID: _storeID,
SupplierID: _SupplierID
},
type: 'POST',
cache: false,
dataType: 'json',
url: url,
success: function (result) {
var newDeliveryDate = '#ViewBag.DeliveryDatebySupplier';
alert(newDeliveryDate);
},
error: function (ex) {
alert("Error getDeliveryDateBySupplier()");
}
});
}
Assuming the action called DeliveryDatebySupplier in the HomeController is the method to set ViewBag.DeliveryDatebySupplier, then this will not work unfortunately.
The script will be generated when the full page was generated and at that time, the value would not have been set yet.
I would advise, rather than using the viewbag, return the value when DeliveryDatebySupplier is called in your script.
Controller will be something like this then
if (ds.Tables[0].Rows.Count == 1)
{
string dt = ds.Tables[0].Rows[0]["DeliveryDt"].ToString();
DateTime myDate = Convert.ToDateTime(dt);
dt = myDate.ToString("yyyy-MM-dd");
return new JsonResult
{
data = new
{
DeliveryDatebySupplier = dt.ToString()
}
};
}
and jquery would change to something like this
success: function (data) {
if (data) {
var newDeliveryDate = data.DeliveryDatebySupplier
alert(newDeliveryDate);
}
else {
//Error
}
},

Success function not working based on submit

I have a Ajax call that is working, but the success function isn't. I have a a few dates that I am inputting, after hitting submit, there should be a little alert popup saying "Data saved to the DB". The data is getting saved to the DB, however I am not getting the popup alert window.
$("#btnSubmit").bind("click", function () {
createUpdateArrays();
var url = "/Sample/Selection";
$.ajax({
type: "GET",
url: url,
data: { ids: ids, dates: dates },
success: function (success) {
if (success === true) {
alert("Success");
}
else {
alert("error");
}
}
});
ids = "";
dates = "";
});
function createUpdateArrays() {
var i = 0;
$('input.remedy-id:checkbox').each(function () {
if ($(this).is(':checked')) {
var rid = $(this).attr("id");
$('.planned-date').each(function () {
var did = $(this).attr("id");
if (did === rid) {
var date = $(this).val();
ids += rid + ",";
dates += date + ",";
}
});
};
});
};
I can't seem to understand the reason behind this..
EDIT: Before doing ANYTHING else, make sure that your server is actually returning a response to begin with.
Your success function is expecting a boolean to be returned by the server, but this is probably not what is happening. If you're returning a simple string "success" from the server, then the comparison should be if (success === "success"). This is entirely dependent on what your server is returning as a response.
Perhaps your server is returning a status code of 2xx. In either case, you can use the jQuery status code callbacks:
$.ajax({
type: "GET",
url: url,
data: { ids: ids, dates: dates },
statusCode: {
200: function(){alert("Success!")},
201: function(){alert("Success!")}
}
});
And if you don't want to do that and just want to use the success callback, try something like this:
success: function (success) {
if (success || (success.length && success.length == 0)) { // this will almost definitely evaluate to true
console.log(success) // Do this to see what is actually being returned. I guarantee it isn't a boolean value.
alert("Success");
}
else {
alert("error");
}
}

Kendo jQuery Spreadsheet Date Values on Save

So I have a Kendo jQuery spreadsheet that is bound to a remote datasource. The fields in the spreadsheet are also data-driven, so I have a process in place that will loop over all of the columns and apply a validation to the column based on the type of data. When I apply the validation to date values it seems like all the values are converted into JavaScript Date objects.
This causes me two problems. 1. When I go to save the data it sends the date object to the server, not a string of the mm/dd/yyyy. 2. It treats blank values as 12/30/1899.
Here is a portion of the code that I use:
var record_id = 1;
var columnData = {
field_name1: {"title":"FIELD1", "type":"string", "width":50, "order":0},
field_name2: {"title":"FIELD2", "type":"date", "width":50, "order":1}
};
var columnMap = ['field_name1', 'field_name2'];
// The following code executes in the event that is triggered when the data is successfully read.
function readSource(e) {
$.ajax({
url: './spreadsheet.php',
data: { id: record_id, action: 'list' },
dataType: 'json',
method: 'POST',
success: function(result) {
e.success(result);
$.each(columnData, function(field, data) {
var range = toColumnName(columnMap.indexOf(field) + 1) + '2:' + toColumnName(columnMap.indexOf(field) + 1) + (result.count + 1);
var validator = false;
var format = '';
switch (data.type) {
case 'date': {
validator = {
dataType: 'date',
comparerType: 'between',
from: 'DATEVALUE("1/1/2000")',
to: 'DATEVALUE("1/1/2100")',
allowNulls: true,
showButton: true,
type: 'reject',
titleTemplate: 'Date Error',
messageTemplate: 'Enter a valid date between 1/1/2000 and 1/1/2100.'
};
format = 'mm/dd/yyyy';
break;
}
}
if (validator !== false) {
sheet.range(range).validation(validator);
}
if (format === '') {
sheet.range(range).format(format);
}
});
}
});
}
// On save
function submitSource(e) {
$.ajax({
url: './spreadsheet.php',
data: { action: 'update', id: record_id, records: e.data },
method: 'POST',
dataType: 'json',
success: function (result) {
e.success(result.Updated, 'update');
e.success(result.Created, 'create');
e.success(result.Destroyed, 'destroy');
}
}
// Convert index to column letter (1 => 'A', 27=>'AA')
function toColumnName(num) {
for (var ret = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) {
ret = String.fromCharCode(parseInt((num % b) / a) + 65) + ret;
}
return ret;
}
I will include a link to a screenshot that shows what happens to cells that should be blank when I click the save button. The first row in the image had dates that were populated. The rows below that were blank.
What needs to change to allow the appropriate date values to be sent back to the server and how can I avoid the trouble with the blanks?
The spreadsheet.php code probably doesn't properly format the date.
December 30, 1899 is the epoch date for Microsoft Excel and others:
https://en.wikipedia.org/wiki/Epoch_(reference_date)#Notable_epoch_dates_in_computing
So you are probably feeding the value "1" instead of null.

BeforeShowDay doesn't changed in datepicker

I have a function to disabled specific days before show date in datepicker, but I have an error: when I call my function in first time it works, but in second call I still have the first result.
For example on the first call I have Sunday disabled, when I call the function again I have Sunday disabled too.
I see that the error is in the variable used in BeforShowDay, is still not changed just inside datepicker, but outside is changer in each call.
This is my code:
function loadFreeDays (etablissement) {
var array=[];
$.ajax({
type: "POST",
url: "/promo3/etablissments/getFreeDays/"+etablissement,
data: {'etablissement': etablissement } ,
dataType: 'json',
success: function(response){
$.each(response, function(i, value) {
array.push(value);
}),
/*console.log(" diasbled days are "+array); here variable still is changed */
$('#datepicker').datepicker({
beforeShowDay: function(date){
/* here array variable still not changed */
for (i = 0; i < array.length; i++) {
if (date.getDay() == array[i][0]) {
return [false];
}
}
var string = jQuery.datepicker.formatDate('d-m-yy', date);
var day = date.getDay();
return [true, ''];
}
});
},
error: function(x, e) { }
});
}
I solve the problem by colling $('#txtDate').datepicker("destroy"); before ajax function.
It work now.

How do I get the changed element in a multiselect, using KendoUI?

I have a multiselect-list that acts as holder for a list of tags. I can't seem to figure out how to properly get the value of the item being changed and passed along with the changed-event. Here's my Kendo multiselect:
#(Html.Kendo().MultiSelect()
.Name("tags")
.Placeholder("No tags selected for this unit")
.BindTo(new SelectList(Model.TagsAvailable))
.Events(e => e
.Select("select")
.Change("change"))
.Value(Model.TagsSelected.ToArray())
)
And here are my js-methods:
function select(e) {
var dataItem = this.dataSource.view()[e.item.index()];
var param = dataItem.Text;
var url = '/UnitDetails/TagUnit/#Model.UnitId';
$.ajax({
url: url,
data: { selectedItem: param },
type: 'GET',
dataType: 'json',
success: function (data) {
// ...
},
error: function () {
// ...
}
});
};
function change(e) {
var dataItem = this;
var param = dataItem.element.context.innerText;
var url = '/UnitDetails/UnTagUnit/#Model.UnitId';
$.ajax({
url: url,
data: { selectedItem: param },
type: 'GET',
dataType: 'json',
success: function (data) {
// ...
},
error: function () {
// ...
}
});
};
My problem beeing that I feel the assignment of param is just quick and dirty. Surely, there must be some other, more correct way of going about this?
There is no easy way (afaik) for knowing the changes. So, let do it by ourselves.
First, I'm going to save the old value using the following function.
function saveCurrent(multi) {
multi._savedOld = multi.value().slice(0);
}
Where multi is the multi-select that we pass to the function as argument (so you can use the function for multiple multiselects).
Then, you need to implement change as follow:
change : function (e) {
// Retrieve previous value of `multiselect` saved using previous function
var previous = this._savedOld;
// These are current values.
var current = this.value();
// Let's save it for the next time
saveCurrent(this);
// The difference between previous and current are removed elements
var diff = $(previous).not(current).get();
console.log("removed", diff);
// The difference between current and previous, are added elements
diff = $(current).not(previous).get();
console.log("added", diff);
}
Running example here http://jsfiddle.net/OnaBai/MapVN/
Nice answer OnaBai! very useful and helpful.
I had the same Nickla's problem.
But, I needed to "save current values" at dataBound event. And it works (logging the changed values).
If you start deleting an item, it fails because the function recognizes the "change" as an "item add".
This is what I did
function dataBound(ev) {
saveCurrent(this);
}
function saveCurrent(multi) {
multi._savedOld = multi.value().slice(0);
}
function change(ev) {
var previous = this._savedOld;
var current = this.value();
saveCurrent(this);
var diff = $(previous).not(current).get();
console.log("removed", diff);
var removedSkill = diff;
console.log("removedSkills", removedSkill);
diff = $(current).not(previous).get();
var addedSkill = diff;
console.log("added", diff);
console.log("addedSkills", addedSkill);
if (addedSkill.length > 1 || removedSkill.length > 1) {
if (addedSkill.length > 1) {
addedSkill = addedSkill[addedSkill.length - 1];
alert("Added skill code: " + addedSkill.toString());
}
if (removedSkill.length > 1) {
removedSkill = removedSkill[removedSkill.length - 1];
alert("Removed skill code: " + removedSkill.toString());
}
}
else {
if (addedSkill.length > 0) {
alert("Added skill code: " + addedSkill.toString());
}
if (removedSkill.length > 0) {
alert("Removed skill code: " + removedSkill.toString());
}
}
$.ajax({
url: "SomeUrl",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({ removedSkill: removedSkill, addedSkill: addedSkill })
});
}
Thanks again!
Iván

Categories