Backbone collection fetch error with no information - ajax

I have a strange problem with the fetch of a backbone collection I am working with. In one particular instance of my code I perform a fetch (exactly how I do it in other areas of the code which all work fine), the fetch never seems to make it to the server and the developer tools shows the request as red with the word (canceled) in the status/text field.
I've walked this through into the backbone sync method and I see the $.ajax being built and everything looks fine. Has anyone run into this problem?
here is my code if it helps, this is a function that calls two .ashx services to first check for a file's existence then to open it. The part that isn't working for me is the "me.collection.fetch().
openDocument: function () {
var me = this,
fileId = me.model.get('id'),
userId = Dashboard.Data.Models.UserModel.get("UserInfo").User_ID,
fileRequest = '/genericHandlers/DownloadFile.ashx?id=' + fileId + '&userId=' + userId,
fileCheck = '/genericHandlers/CheckFileExistance.ashx?id=' + fileId + '&userId=' + userId;
//hide tooltip
me.hideButtonTooltips();
// Check for file existance
$.ajax({
url: fileCheck
})
.done(function (data) {
if (data && data === "true") {
document.location.href = fileRequest;
me.collection.fetch();
} else if (!!data && data === "false") {
"This file is no longer available.".notify('error');
}
})
.fail(function (data) {
"Something went wrong during the File Existance check".notify('error');
"Something went wrong during the File Existance check".log(userId, 'error', 'Docs');
});
},
my collection:
// docsCollection.js - The collection of ALL the documents available to a given user
// Document Collection
Dashboard.Collections.DocsCollection = Backbone.Collection.extend({
model: Dashboard.Models.DocumentUploadModel,
url: function () {
return 'apps/docs/Docs/' + this.userId;
},
initialize: function (options) {
this.userId = options.userId;
this.deferredFetch = this.fetch();
},
comparator: function (model) {
return -(new Date(model.get('expirationDate')));
},
getDaysSinceViewedDocuments: function () {
return this.filter(function (model) {
return model.get('daysSinceViewed') !== null;
});
},
getNewDocuments: function () {
return this.filter(function (model) {
return model.get('isNew');
});
},
getExpiredDocuments: function () {
return this.filter(function (model) {
return model.get('isExpired');
});
}
});
and my model:
Dashboard.Models.DocumentUploadModel = Backbone.Model.extend({
defaults: {
fileArray: [],
name: '',
description: '',
accesses: [],
tags: [],
expirationDate: ''
},
initialize: function () {
this.set({
userId: Dashboard.Data.Models.UserModel.get("UserInfo").User_ID,
expirationDate: (this.isNew()) ? buildExpirationDate() : this.get('expirationDate')
}, { silent: true });
function buildExpirationDate() {
var date = new Date((new Date()).getTime() + 24 * 60 * 60 * 1000 * 7),
dateString = "{0}/{1}/{2}".format(date.getMonth() + 1, date.getDate(), date.getFullYear());
return dateString;
}
},
firstFile: function () {
return this.get('fileArray')[0];
},
validate: function (attributes) {
var errors = [];
if (attributes.name === '' || attributes.name.length === 0)
errors.push({
input: 'input.txtName',
message: "You must enter a name."
});
if (attributes.description === '' || attributes.description.length === 0)
errors.push({
input: 'textarea.taDescription',
message: "You must enter a description."
});
if (errors.length > 0)
return errors;
return;
},
sync: function (method, model, options) {
var formData = new FormData(),
files = model.get("fileArray"),
$progress = $('progress'),
success = options.success,
error = options.error;
// Nothing other than create or update right now
if (method !== "create" && method !== "update")
return;
// Build formData object
formData.append("name", model.get("name"));
formData.append("description", model.get("description"));
formData.append("accesses", model.get("accesses"));
formData.append("tags", model.get("tags"));
formData.append("expirationDate", model.get("expirationDate"));
formData.append("userId", model.get("userId"));
formData.append("isNew", model.isNew());
// if not new then capture id
if (!model.isNew())
formData.append('id', model.id);
for (var i = 0; i < files.length; i++) {
formData.append('file', files[i]);
}
xhr = new XMLHttpRequest();
xhr.open('POST', '/genericHandlers/UploadDocsFile.ashx');
xhr.onload = function () {
if (xhr.status === 200) {
if (success)
success();
} else {
if (error)
error();
}
}
if ($progress.length > 0) {
xhr.upload.onprogress = function (evt) {
var complete;
if (evt.lengthComputable) {
// Do the division but if you cant put 0
complete = (evt.loaded / evt.total * 100 | 0);
$progress[0].value = $progress[0].innerHTML = complete;
}
}
}
xhr.send(formData);
},
upload: function (changedAttrs, options) {
this.save("create", changedAttrs, options);
}
});

You're assigning a value to document.location.href before you try to fetch your collection:
document.location.href = fileRequest;
me.collection.fetch();
Changing document.location.href will change the whole page and in the process, any currently running JavaScript will get shutdown so I wouldn't expect your me.collection.fetch() to ever get executed.

Related

how i make a condition with ajax and asp mvc

I want to put a condition if the user want to add a second appointment he receives an alert
function SaveEvent(data) {
$.ajax({
type: "POST",
url: '/home/SaveEvent',
data: data,
success: function (data) {
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function () {
alert('Failed');
}
})
}
})
this is my code in controller :
public JsonResult SaveEvent(Event e)
{
var status = false;
if (e.EventID > 0)
{
//Update the event
var v = db.Events.Where(a => a.EventID == e.EventID).FirstOrDefault();
if (v != null)
{
v.EventTitle = e.EventTitle;
v.StartDate = e.StartDate;
v.EndDate = e.EndDate;
v.EventDescription = e.EventDescription;
v.EventID = e.EventID;
v.ThemeColor = e.ThemeColor;
}
else
db.Events.Add(e);
db.SaveChanges();
status = true;
}
i want to make the user add one time his event and receive an alert i try but not work
I think i can help:
if(Session["appointment"] != "ok")<>
{
if (e.EventID > 0)
{
//Update the event
var v = db.Events.Where(a => a.EventID == e.EventID).FirstOrDefault();
if (v != null)
{
v.EventTitle = e.EventTitle;
v.StartDate = e.StartDate;
v.EndDate = e.EndDate;
v.EventDescription = e.EventDescription;
v.EventID = e.EventID;
v.ThemeColor = e.ThemeColor;
}
else
db.Events.Add(e);
db.SaveChanges();
Session["appointment"] = "ok";
return JSON(new{appointment="ok"});
}
}else
{
return JSON(new {appointment="no-good");
}
and controller:
function SaveEvent(data)
{
$.ajax({
type: "POST",
url: '/home/SaveEvent',
data: data,
success: function(data) {
if (data.appointment == "ok")
{
//Refresh the calender
FetchEventAndRenderCalendar();
$('#myModalSave').modal('hide');
}
else { your msg error here }
},
error: function() {
alert('Failed');
}
})
}
})
dont not forget Session.Clear();
as the user logs out

AJAX error return ModelState Error

On my Create page I am using ajax and calling my api controller when creating a person:
<script>
$(document).ready(function() {
var newUrl = '#Url.Action("Index", "PersonInformations")';
var settings = {};
settings.baseUri = '#Request.ApplicationPath';
var infoGetUrl = "";
if (settings.baseUri === "/ProjectNameOnServer") {
infoGetUrl = settings.baseUri + "/api/personinformations/";
} else {
infoGetUrl = settings.baseUri + "api/personinformations/";
}
$("#Create-Btn").on("click",
function(e) {
$("form").validate({
submitHandler: function () {
e.preventDefault();
$.ajax({
method: "POST",
url: infoGetUrl,
data: $("form").serialize(),
success: function () {
toastr.options = {
onHidden: function () {
window.location.href = newUrl;
},
timeOut: 3000
}
toastr.success("Individual successfully created.");
},
error: function (jqXHR, textStatus, errorThrown) {
var status = capitalizeFirstLetter(textStatus);
var error = $.parseJSON(jqXHR.responseText);
//console.log(jqXHR.responseText);
toastr.error(status + " - " + error.message);
}
});
}
});
});
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
});
</script>
Here is the method in my PersonInformations API controller:
[ResponseType(typeof(PersonInformation))]
public IHttpActionResult PostPersonInformation(PersonInformation personInformation)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var lstOfPersons = db.PersonInformations.Where(x => x.deleted == false).ToList();
if (lstOfPersons.Any(
x =>
x.FirstName == personInformation.FirstName && x.LastName == personInformation.LastName &&
x.AId == personInformation.AgencyId && x.ID != personInformation.ID))
{
ModelState.AddModelError("", "This person already exists!");
return BadRequest(ModelState);
}
if (
lstOfPersons.Any(
x => x.Email.ToLower() == personInformation.Email.ToLower() && x.ID != personInformation.ID))
{
ModelState.AddModelError(personInformation.Email, "This email already exists!");
return BadRequest(ModelState);
}
personInformation.FirstName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(personInformation.FirstName);
personInformation.LastName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(personInformation.LastName);
db.PersonInformation.Add(personInformation);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = personInformation.ID }, personInformation);
}
Now when I test this and purposely enter an email that already exists, the ajax request errors out but returns the message:
Error - The Request is invalid
but when I use console.log(jqXHR.responseText)
I get this:
Create
{
"$id": "1",
"message": "The request is invalid.",
"modelState": {
"$id": "2",
"test#test.com": [
"This email already exists!"
]
}
}
How do I get the "This email already exists!" as the error message?
I just figured this out. I know that the modelState was an array type, and the 2nd value was the actual email address entered.
So I edited my button.click event to this:
$("#Create-Btn").on("click",
function(e) {
$("form").validate({
submitHandler: function () {
e.preventDefault();
var emailValue = $("#Email").val();
$.ajax({
method: "POST",
url: infoGetUrl,
data: $("form").serialize(),
success: function () {
toastr.options = {
onHidden: function () {
window.location.href = newUrl;
},
timeOut: 3000
}
toastr.success("Individual successfully created.");
},
error: function (jqXHR, textStatus, errorThrown) {
var status = capitalizeFirstLetter(textStatus);
var error = $.parseJSON(jqXHR.responseText);
toastr.error(status + " - " + error.modelState[emailValue]);
}
});
}
});
});
Find the error message via array bracket notation along with getting the actual value of the email trying to be submitted did the trick.

Knockout JS validation message repeating twice

New to Knockoutjs, Just trying to fix an existing bug in validation message. Below mentioned extend validation messages repeating twice in the UI.
$.each(viewModel.Form.Questions(), function () {
var currentQuestion = this;
debugger;
$.each(currentQuestion.QuestionAnswers(), function () {
var text = this.AnswerDisplay();
this.AnswerValue.extend({
required: {
message: text + " : Question price is required",
onlyIf: function () {
return viewModel.Form.FormPrice.PricingMode() == 2;
}
},
min: {
message: text + " : Question price should be a number",
onlyIf: function () {
return viewModel.SelectedQuestion() != null && currentQuestion.FormQuestionId() == viewModel.SelectedQuestion().FormQuestionId() && viewModel.Form.FormPrice.PricingMode() == 2;
},
params: 0
}
});
});
});

How to stop Kendo UI dropdown from sorting alphabetically

I have been given the fun job on taking on someone elses code and trying to figure it out...
I have been tearing my hair out trying to figure out how to to stop a Kendo UI dropdown from sorting alphabetically ?
<select id="ddlArtworkStatuses" onlyPreparedValues="true"
readOnlyInput="true" data-bind="idNameOptions: artworkStatuses,
comboboxSelectedValue: artworkStatusId"></select>
For some reason this sorts althabetically but I want it to keep the order in the datasource. I have double checked to make sure it is in the order I want.
It doesn't use the standard way of using Kendo UI and I can't find any examples anywhere of using it this way?
It binds the view to the model with this line at the top of the view I believe?
<!-- ko with: fabricationModel -->
The vm.fabrication file is this:
(function (app) {
app.namespace("models");
var resources = {
unableToDeleteArtworkMessage: "This artwork cannot be deleted because it is linked to one or more of the following: Movements, Shows, POs. Or it has Imported Costs, Sales or Restoration Cases.",
unableToBlankArtworkFullyMessage: "This artwork has some data that will not be blanked if you continue. This could be one or more of the following: Movements, Shows, POs, Imported Costs, Sales or Restoration Cases. Do you want to continue?",
deleteArtworkTitle: "Delete artwork",
blankArtworkTitle: "Blank Artwork",
duplicateTitle: "New artwork form is pre-populated",
duplicateMessage: "You can make changes to Fabrication form fields. Record will be created after you press save button",
saveError: 'An error occured during artwork saving. Changes were not saved.'
};
app.models.FabricationModel = function (datasource) {
var emitter = new app.events.EventEmitter(),
self = this,
duplicateArtwork = ko.observable(false);
this.isNewArtwork = ko.observable(false);
this.isActivated = ko.observable(false);
this.showCreationInformation = ko.observable(true);
this.wipeArtworkModel = new app.models.WipeArtworkDialogModel(datasource);
this.internalArtworkModel = ko.observable();
this.editCategoryModel = new app.models.EditDhCategoryModel();
// alert("data=" + this.artworkStatuses);
this.isReadOnly = ko.computed(function () {
if (!self.internalArtworkModel()) {
return true;
}
return self.internalArtworkModel().isReadOnly();
});
this.canSaveStudioStatusOnly = ko.computed(function () {
if (!self.internalArtworkModel()) {
return false;
}
return self.internalArtworkModel().isUnblockStatusActive()
&& self.internalArtworkModel().isReadOnly()
&& self.internalArtworkModel().isStudioStatusVisible();
});
this.canSaveCatRaisOnly = ko.computed(function () {
if (!self.internalArtworkModel()) {
return false;
}
return self.internalArtworkModel().isReadOnly()
&& self.internalArtworkModel().isArchiveProvenanceWriter();
});
this.isNewOrDuplicating = ko.computed(function () {
return self.isNewArtwork() || duplicateArtwork();
});
this.activate = function (params) {
var id = params.id || 0;
self.isNewArtwork(!id);
return self.loadArtworkDetails(id);
};
this.isValid = function () {
return self.internalArtworkModel() && self.internalArtworkModel().errors().length == 0;
};
this.loadArtworkDetails = function (id) {
var action = self.isNewArtwork() ? datasource.artworks.getEmpty : datasource.artworks.getById;
return action(id)
.done(function (result) {
var mapper = app.mappers["fabrication"],
model = mapper.map(result.data);
self.internalArtworkModel(model);
self.editCategoryModel.categoryId(model.defaultDhCategoryId);
self.editCategoryModel.setModeAsCategoryChanging();
if (self.isNewArtwork()) {
self.editCategoryModel.setModeAsCreation();
self.editCategoryModel.show();
}
self.isActivated(true);
duplicateArtwork(false);
$("a#science-link").attr("href", window.location.href);
triggerLoadEvent();
});
};
this.saveArtwork = function () {
if (self.isValid()) {
return saveInternal($.noop);
}
};
this.editCategory = function () {
self.editCategoryModel.show();
};
this.onLoad = function (callback) {
emitter.subscribe("load", callback);
};
this.onCategoryChanged = function (callback) {
emitter.subscribe("category-changed", callback);
};
this.onDelete = function (callback) {
emitter.subscribe("delete", callback);
};
this.onCreated = function (callback) {
emitter.subscribe("artwork-created", callback);
};
this.onUpdated = function (callback) {
emitter.subscribe("artwork-updated", callback);
};
this.onBlanked = function (callback) {
emitter.subscribe("blanked", callback);
};
this.saveStudioStatusInt = function () {
return saveStudioStatusInternal($.noop);
};
this.saveCatRaisInt = function () {
return saveCatRaisInternal($.noop);
};
this.saveStudioStatus = ko.asyncCommand({
execute: function (complete) {
saveStudioStatusInternal(complete);
},
canExecute: function (isExecuting) {
return !isExecuting && self.canSaveStudioStatusOnly();
}
});
this.saveCatRais = ko.asyncCommand({
execute: function (complete) {
saveCatRaisInternal(complete);
},
canExecute: function (isExecuting) {
return !isExecuting && self.canSaveCatRaisOnly();
}
});
this.save = ko.asyncCommand({
execute: function (complete) {
return saveInternal(complete);
},
canExecute: function (isExecuting) {
if (!self.isValid()) {
showErrors();
}
return !isExecuting && self.isValid();
}
});
function saveStudioStatusInternal(completeCallback) {
var model = self.internalArtworkModel();
triggerSaveStudioStatusEvent();
datasource.artworks.saveStudioStatus(model.artworkId(), model.artworkStatusId(), model.studioStatusId).always(completeCallback);
}
function saveCatRaisInternal(completeCallback) {
var model = self.internalArtworkModel();
triggerSaveStudioStatusEvent();
datasource.artworks.saveCatRais(model.artworkId(), model.inclusion(), model.image(), model.details(), model.crReady(), model.selectedVolume.selected.value).always(completeCallback);
}
this.onSaveStudioStatus = function (callback) {
emitter.subscribe("saveStudioStatus", callback);
};
function triggerSaveStudioStatusEvent() {
emitter.publish("saveStudioStatus");
}
this.beginArtworkDeletion = function () {
if (!self.internalArtworkModel().canBeBlanked) {
jAlert(resources.unableToDeleteArtworkMessage, resources.deleteArtworkTitle);
return;
}
self.wipeArtworkModel.beginArtworkDeletion(self.internalArtworkModel().artworkId());
};
this.beginArtworkBlanking = function () {
if (!self.internalArtworkModel().canBeBlanked) {
//jAlert(resources.unableToBlankArtworkMessage, resources.blankArtworkTitle);
app.alerts.appConfirm(resources.unableToBlankArtworkFullyMessage, resources.blankArtworkTitle, function (ok) {
if (ok) {
self.wipeArtworkModel.beginArtworkBlanking(self.internalArtworkModel().artworkId());
}
});
return;
}
self.wipeArtworkModel.beginArtworkBlanking(self.internalArtworkModel().artworkId());
};
this.duplicateArtwork = function () {
if (!self.internalArtworkModel()) {
return;
}
duplicateArtwork(true);
resetModelBeforeDuplication();
if (self.isValid()) {
showErrors();
}
jAlert(resources.duplicateMessage, resources.duplicateTitle);
};
function saveInternal(completeCallback) {
var mapper = app.mappers["fabrication"];
//alert("saving now...");
var unmappedModel = mapper.toJS(self.internalArtworkModel());
if (duplicateArtwork()) {
return saveDuplicatedArtwork(unmappedModel, completeCallback);
}
if (unmappedModel.artworkId) {
return updateArtwork(unmappedModel, completeCallback);
}
return createArtwork(unmappedModel, completeCallback);
}
function saveDuplicatedArtwork(model, completeCallback) {
return datasource.artworks.duplicate(model)
.always(completeCallback)
.fail(function (response) {
jAlert(resources.saveError);
})
.done(function (id) {
triggerArtworkCreatedEvent(id);
duplicateArtwork(false);
self.showCreationInformation(true);
});
}
function updateArtwork(model, completeCallback) {
return datasource.artworks.save(model)
.always(completeCallback)
.fail(function (response) {
jAlert(resources.saveError);
})
.done(function (result) {
if (!result) {
return;
}
var mapper = app.mappers["fabrication"],
mappedModel = mapper.map(result.data);
triggerUpdateEvent(
{
dhCategory: mappedModel.dhCategory(),
refNumber: mappedModel.refNumber(),
computedTitle: mappedModel.computedTitle()
});
self.internalArtworkModel(mappedModel);
});
}
function createArtwork(model, completeCallback) {
return datasource.artworks.save(model)
.always(completeCallback)
.fail(function (response) {
jAlert(resources.saveError);
})
.done(function (id) {
if (id) {
triggerArtworkCreatedEvent(id);
}
});
}
function triggerLoadEvent() {
var model = self.internalArtworkModel();
emitter.publish("load", {
artworkId: model.artworkId() || 0,
dhCategory: model.dhCategory() || "",
refNumber: model.refNumber() || "",
computedTitle: model.computedTitle() || "",
isForSale: model.isForSale
});
}
function triggerArtworkCreatedEvent(artworkId) {
emitter.publish("artwork-created", artworkId);
}
function triggerCategoryChangedEvent() {
emitter.publish("category-changed", {
name: self.internalArtworkModel().dhCategoryName(),
id: self.internalArtworkModel().dhCategoryId()
});
}
function triggerDeleteEvent(e, artworkId) {
emitter.publish("delete", artworkId);
}
function triggerUpdateEvent(data) {
var model = self.internalArtworkModel();
data.isCategoryChanged = model.initialCategoryId !== model.dhCategoryId();
emitter.publish("artwork-updated", data);
}
function showErrors() {
var model = self.internalArtworkModel();
if (model) {
model.errors.showAllMessages();
}
}
function resetModelBeforeDuplication() {
var model = self.internalArtworkModel();
model.refNumber("");
model.computedTitle("");
model.isOnDisplay(false);
model.isOnRestoration(false);
model.salesStatus("Not set");
model.creationDate("");
model.creatorName("");
model.isFramed(false);
model.framedDate("");
model.framedUserName("");
model.framedUserInitials("");
model.framedUserId(null);
model.locations(null);
model.isInsuranceComponent(false);
model.dateWebsiteWork("");
model.dateWebsiteReady("");
model.dateWebsiteUploaded("");
model.dateRemovedFromWebsite("");
model.collectionListing("");
model.salesStatusChangedDate("");
model.salesStatusChangerUserInitials("");
model.salesStatusChangerUserName("");
self.showCreationInformation(false);
}
function triggerBlanked(artworkId) {
emitter.publish("blanked", { artworkId: artworkId, flag: true });
}
(function () {
self.editCategoryModel.onChanged(function (e, categoryId) {
self.internalArtworkModel().dhCategoryId(categoryId);
triggerCategoryChangedEvent();
});
self.editCategoryModel.onCancel(function () {
if (self.isNewArtwork()) {
self.isNewArtwork(false);
app.router.back();
}
});
self.wipeArtworkModel.onDelete(triggerDeleteEvent);
self.wipeArtworkModel.onBlank(function (e, artworkId) {
self.loadArtworkDetails(artworkId);
triggerBlanked(artworkId);
});
})();
};
})(app);
It also uses a mapper:
(function (app, ko) {
app.namespace("mappers");
var s = app.urls.shared,
datasource = app.datasource;
var mapSettings = {
selectedMedium: {
create: function (options) {
return new ListModel({
isRemoteSource: true,
url: s.get('dictionaryUrl'),
listType: datasource.dictionaryTypes.get("medium"),
currentValue: options.data,
nobutton: true,
templateName: "textAreaTemplate"
});
}
},
artist: {
create: function (options) {
return new ListModel({
isRemoteSource: true,
url: s.get('dictionaryUrl'),
listType: datasource.dictionaryTypes.get("artist"),
currentValue: options.data,
onlyPreparedValues: false
});
}
},
manager: {
create: function (options) {
return new ListModel({
isRemoteSource: true,
url: s.get('dictionaryUrl'),
listType: datasource.dictionaryTypes.get("manager"),
currentValue: options.data,
onlyPreparedValues: false
});
}
},
managerStatus: {
create: function (options) {
return new ListModel({
isRemoteSource: true,
url: s.get('dictionaryUrl'),
listType: datasource.dictionaryTypes.get("managerStatus"),
currentValue: options.data,
onlyPreparedValues: false
});
}
},
selectedVolume: {
create: function (options) {
return new ListModel({
isRemoteSource: true,
url: s.get('dictionaryUrl'),
listType: datasource.dictionaryTypes.get("volume"),
currentValue: options.data,
onlyPreparedValues: false,
readonly: !options.parent.isArchiveProvenanceWriter(),
editable: options.parent.isArchiveProvenanceWriter()
});
}
},
salesStatus: {
create: function (options) {
var value = options.data || "Not set";
return ko.observable(value);
}
},
oldReferences: {
create: function (options) {
return ko.observable(options.data);
}
},
copy: ['defaultDhCategoryId', "canBeDeleted", "canBeBlanked", "isForSale"],
ignore: ["dimensions", "dimensionUnits", "selectedMediumTypes", "selectedSeries", "selectedSubSeries", "selectedAkaNames", "selectedWebSiteMediumTypes", 'selectedWebSiteCategoryIds', "locations", "hasInTransitLocations"]
},
unmapSettings = {
ignore: ["selectedMedium", "artist", "manager", "managerStatus", "mediumTypesModel", "dimensionModel", "seriesModel", "subSeriesModel", "akaModel", "webSiteMediumTypesModel", "webSiteCategoriesModel", "selectedVolume"]
},
map = function (json) {
var convertedObject = ko.utils.parseJson(json);
var model = ko.mapping.fromJS(convertedObject, mapSettings);
model.artworkStatusesModel = new ListModel({
isRemoteSource: false,
currentValue: convertedObject.selectedArtworkStatus,
data: convertedObject.artworkStatuses,
//data: filteredSalesStatuses,
onlyPreparedValues: true,
allowNull: false,
readonly: true
});
alert("mooo=" + model.artworkStatuses()[0].name());
alert("mooo=" + model.artworkStatuses()[1].name());
alert("mooo=" + model.artworkStatuses()[2].name());
//alert("mooo=" + model.artworkStatuses()[3].name());
//alert("mooo=" + model.artworkStatuses()[4].name());
model.dhCategoryName = ko.computed(function () {
var categories = model.dhCategories();
for (var i = 0; i < categories.length; i++) {
var category = categories[i];
if (category.id() == model.dhCategoryId()) {
return category.name();
}
}
return "";
});
model.initialCategoryId = convertedObject.dhCategoryId;
model.dimensionModel = new app.models.DimensionModel(convertedObject.dimensions);
ko.utils.arrayForEach(convertedObject.dimensionUnits, function (unit) {
model.dimensionModel.units.push(unit);
});
model.locations = ko.observable(convertedObject.locations ? {
archivedLocations: $.map(convertedObject.locations, function (elem) {
return elem.isArchived ? elem : null;
}),
activeLocations: $.map(convertedObject.locations, function (elem) {
return elem.isArchived ? null : elem;
}),
hasInTransitLocations: convertedObject.hasInTransitLocations
} : convertedObject.locations);
model.mediumTypesModel = new app.models.MultilistModel(convertedObject.selectedMediumTypes, { url: s.get("mediumTypesUrl") });
model.seriesModel = new app.models.MultilistModel(convertedObject.selectedSeries, { url: s.get("seriesUrl") });
model.subSeriesModel = new app.models.MultilistModel(convertedObject.selectedSubSeries, { url: s.get("subSeriesUrl") });
model.akaModel = new app.models.MultilistModel(convertedObject.selectedAkaNames, { url: s.get("akaUrl") });
model.webSiteMediumTypesModel = new app.models.MultilistModel(convertedObject.selectedWebSiteMediumTypes, { url: s.get("webSiteMediumTypeUrl") });
model.webSiteCategoriesModel = new app.models.MultilistModel(convertedObject.selectedWebSiteCategories, { url: s.get("webSiteCategoryUrl") });
model.isStudioStatusVisible = ko.computed(function () {
var foundStatuses = ko.utils.arrayFilter(model.artworkStatuses(), function (status) {
return status.id() == model.artworkStatusId();
});
var currentStatus = foundStatuses[0];
if (currentStatus) {
return currentStatus.name().toLowerCase() == "in progress";
}
return false;
});
addValidationOptions(model);
return model;
},
toJS = function (artwork) {
var result = ko.mapping.toJS(artwork, unmapSettings);
result.artist = artwork.artist.toJS();
result.manager = artwork.manager.toJS();
result.managerStatus = artwork.managerStatus.toJS();
result.selectedMedium = artwork.selectedMedium.toJS();
result.selectedVolume = artwork.selectedVolume.toJS();
result.dimensions = artwork.dimensionModel.toJS();
result.selectedMediumTypes = artwork.mediumTypesModel.toJS();
result.selectedSeries = artwork.seriesModel.toJS();
result.selectedSubSeries = artwork.subSeriesModel.toJS();
result.selectedAkaNames = artwork.akaModel.toJS();
result.selectedWebSiteMediumTypes = artwork.webSiteMediumTypesModel.toJS();
result.selectedWebSiteCategories = artwork.webSiteCategoriesModel.toJS();
return result;
};
function isValidationRequired(model) {
var artworkStatus = ko.utils.unwrapObservable(model.artworkStatusId);
var dhCategory = ko.utils.unwrapObservable(model.dhCategoryId);
return artworkStatus == app.global.dictionary.get("compiteArtworkStatus")
&& dhCategory != app.global.dictionary.get("ignoreDHCatigory");
}
function addValidationOptions(model) {
model.artworkStatusId.extend({ required: true });
model.title.extend({ required: true });
model.artist.selected.value.extend({ required: true });
model.startYear.extend({
lessEqualThan: {
params: model.endYear,
onlyIf: function () {
return (model.endYear() != undefined && model.endYear() != null);
},
message: 'From Date should be less or equal than a To Date'
}
});
model.endYear.extend({
required: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "To Date field is required"
}
});
model.selectedMedium.selected.value.extend({
required: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "Medium is required"
}
});
model.mediumTypesModel.hasValue.extend({
equal: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "Medium Type is required"
}
});
model.akaModel.hasValue.extend({
equal: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "Aka is required"
}
});
model.isInsuranceComponent.extend({
equal: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "At least 1 Insurance component should be chosen"
}
});
model.dimensionModel.hasDimensions.extend({
equal: {
params: true,
onlyIf: function () {
return isValidationRequired(model);
},
message: "The Dimension fields should be filled"
}
});
model.errors = ko.validation.group(model, { deep: true });
}
app.mappers.fabrication = {
settings: mapSettings,
map: map,
toJS: toJS
};
})(app, ko);
Where I have the alerts, the items are in the right order, so somewhere they are getting sorted but cant find out where?!
I hope someone can help?
It would be really appreciated.
Many thanks,
David.

Adding new row to SlickGrid

I have a slickgrid using the dataview. From what I can tell, the grid's add new row event isn't called until after the first new row field's editor is complete. The field I was editing is a custom editor that uses a input box with autocomplete and save the selected item "value" to the grid source data. The problem is the new "item" source isn't created until the grid add new row event is fired. I know there is a way around this and just want to know what is the best way to solve for this.
Thanks.
//Add new row event
grid.onAddNewRow.subscribe(function (e, args) {
var item = args.item;
addnewid = addnewid - 1;
item.inventorytransferdetailid = addnewid;
$.extend(item, args.item);
dataView.addItem(item);
});
// Custom editor
function Suggest2(args) {
var $input;
var defaultValue;
var scope = this;
this.init = function () {
$input = $("<INPUT type=text class='editor-text' />")
$input.width = args.column.width;
$input.appendTo(args.container);
$input.focus();
$input.bind("keydown.nav", function (e) {
if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
e.stopImmediatePropagation();
}
else if ($input.val().length > 0) {
$.ajax({
type: "GET",
url: "http://localhost:11111/GetProducts/" + $input.val(),
dataType: "json",
data: "{}",
contentType: "application/json; charset=utf-8",
success: function (data) {
$input.autocomplete({
source: data,
select: function (event, ui) {
var v = ui.item.value;
var l = ui.item.label;
//Set "display" field with label
args.item[args.column.field] = l;
this.value = l;
//Set "hidden" id field with value
args.item["productid"] = v;
return false;
}
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
}
})
};
this.destroy = function () {
$input.remove();
};
this.focus = function () {
$input.focus();
};
this.getValue = function () {
return $input.val();
};
this.setValue = function (val) {
$input.val(val);
};
this.loadValue = function (item) {
defaultValue = item[args.column.field] || "";
$input.val(defaultValue);
$input[0].defaultValue = defaultValue;
$input.select();
};
this.serializeValue = function () {
return $input.val();
};
this.applyValue = function (item, state) {
//item[args.column.field] = state;
};
this.isValueChanged = function () {
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
};
this.validate = function () {
if (args.column.validator) {
var validationResults = args.column.validator($input.val());
if (!validationResults.valid) {
return validationResults;
}
}
return {
valid: true,
msg: null
};
};
this.init();
}
You can try below code.
function add_new_row(){
item = {
"id": (Math.round(Math.random()*-10000))
};
data_view.insertItem(0, item);
}
Then, bind with button.
<button onclick="add_new_row()">Add Row</button>

Resources