I need to add a href to thumbnail in fine-uploader and use addInitialFiles function. My problem is that I don't have any event handler to call after each file is added, right?
callbacks:{
onValidate: function(dados, buttonContainer) {
alert('onValidate');
},
onSessionRequestComplete: function(arr, response, success) {
alert('onSessionRequestComplete');
},
onComplete: function(id, name, response) {
alert('onComplete');
if (response.success) {
var serverPathToFile = response.url+'/'+response.uuid+'/'+response.name, fileItem = this.getItemByFileId(id);
var viewTnh = qq(fileItem).getByClass("qq-thumbnail-link")[0];
viewTnh.setAttribute("href", serverPathToFile);
}
}
},
...
var numFiles = 0;
var prova = cVs['6'][p][a]['provas']['prova'];
$.each(cVs['30'][p], function(a){
galleryUploader.addInitialFiles({
numFiles:{
"name":cVs['30'][p][a]["imagens_provas"]['ficheiro'],
"uuid":cVs['30'][p][a]["imagens_provas"]['uuid'],
"size":'111',
"thumbnailUrl":"uploads/Provas/users/Admin/"+prova+"/respostas/"+cVs['30'][p][a]["imagens_provas"]['uuid']+"/thumb_"+cVs['30'][p][a]["imagens_provas"]['ficheiro'],
"fileUrl":"uploads/Provas/users/Admin/"+prova+"/respostas/"+cVs['30'][p][a]["imagens_provas"]['uuid']+"/"+cVs['30'][p][a]["imagens_provas"]['ficheiro'],
"numero":"115"
}
});
numFiles++;
});
The result:
var galleryUploader = new qq.FineUploader({
element: document.getElementById("fine-uploader-gallery"),
template: 'qq-template-gallery',
request: {
endpoint: 'modules.php?name=Logos_9&opt=30_put&prova='+cVs['6'][p][a]['provas']['prova']
},
session: {
endpoint: 'modules.php?name=Logos_9&opt=30a_get&prova='+cVs['6'][p][a]['provas']['prova'],
refreshOnReset: true
},
thumbnails: {
placeholders: {
waitingPath: 'includes/FineUploader/placeholders/waiting-generic.png',
notAvailablePath: 'includes/FineUploader/placeholders/not_available-generic.png'
}
},
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png']
},
chunking: {
enabled: true,
partSize: 200000,
concurrent: {
enabled: true
},
success: {
endpoint: 'modules.php?name=Logos_9&done&opt=30_put&prova='+cVs['6'][p][a]['provas']['prova']
}
},
deleteFile: {
//not yet
},
scaling: {
sendOriginal: false,
sizes: [
//{name: "small", maxSize: 100},
{name: "", maxSize: 1684}
]
},
callbacks:{
onSessionRequestComplete: function(response, success) {
if (success) {
$.each(response, function(a, obj) {
//response[a] ex.
//{
// "id":"12",
// "name":"PROV02.jpg",
// "uuid":"aa60f02e-29a4-4826-96d3-39709b39a664",
// "size":"?",
// "aluno_id":1,
// "estado":"2",
// "thumbnailUrl":"uploads/Provas/users/User_n/1/respostas/aa60f02e-29a4-4826-96d3-39709b39a664/thumb_PROV02.jpg",
// "fileUrl":"uploads/Provas/users/User_n/1/respostas/aa60f02e-29a4-4826-96d3-39709b39a664/test_PROV02.jpg"
//}
var serverPathToFile = obj.fileUrl;
var viewTnh = document.getElementsByClassName('qq-file-id-'+a)[0].getElementsByClassName('qq-thumbnail-wrapper')[0].getElementsByClassName('qq-thumbnail-link')[0];
viewTnh.setAttribute("href", serverPathToFile);
var number = obj.aluno_id;
var viewNum = document.getElementsByClassName('qq-file-id-'+a)[0].getElementsByClassName('qq-file-info')[0].getElementsByClassName('qq-numero')[0];
viewNum.innerHTML = number;
if(obj.estado == "1") {
var corEstado = "background-color: #50FF00;";
obj.estado = "2";
}
else if(obj.estado == "2") {
var corEstado = "background-color: #FFFF00;";
obj.estado = "3";
}
else if(obj.estado == "3") {
var corEstado = "background-color: #FF0000;";
obj.estado = "1";
}
var viewTnh = document.getElementsByClassName('qq-file-id-'+a)[0];
viewTnh.setAttribute("style", corEstado);
});
}
},
onComplete: function(id, name, response) {
if (response.success) {
//response ex.
//{
//) "success":true,
// "uuid":"23d1612b-7d32-49ab-8157-dae3bf19be7a",
// "name":"PROV08.jpg",
// "url":"uploads/Provas/users/Admin/1/respostas",
// "student_id":7,
// "estado":"2"
//}
//PLACE LINK IN THUMBNAIL
var serverPathToFile = response.url+'/'+response.uuid+'/'+response.name, fileItem = this.getItemByFileId(id);
var viewTnh = qq(fileItem).getByClass("qq-thumbnail-link")[0];
viewTnh.setAttribute("href", serverPathToFile);
//REDEFINE THE NEW THUMBNAIL IMAGEM
var serverPathToFile = response.url+'/'+response.uuid+'/thumb_'+response.name, fileItem = this.getItemByFileId(id);
var viewTnh = qq(fileItem).getByClass("qq-thumbnail-link")[0].getElementsByClassName('qq-thumbnail-selector')[0];
viewTnh.src = serverPathToFile;
//SHOW STUDENT NUMBER IN THUMBNAIL
var number = response.student_id;
if(number <= 0) number = '???';
var viewNum = qq(fileItem).getByClass('qq-file-info')[0].getElementsByClassName('qq-numero')[0];
viewNum.innerHTML = number;
//CHANGE COLOR IN THUMBAIL
if(response.estado == "1") {
var corEstado = "background-color: #50FF00;";
}
else if(response.estado == "2") {
var corEstado = "background-color: #FFFF00;";
}
else if(response.estado == "3") {
var corEstado = "background-color: #FF0000;";
}
var viewTnh = fileItem.getElementsByClassName('qq-thumbnail-wrapper')[0].parentNode;
viewTnh.setAttribute("style", corEstado);
}
}
},
messages:{
'onLeave':'Os ficheiros estão a ser carregados para o servidor, se sair agora o carregamento vai ser cancelado.',
'sizeError':'Free account are limited to: 29.297 GB, please login for more options',
'emptyError':'O ficheiro {file} está vazio'
}
});
Related
I'm having trouble either understanding or implementing search/filter functionality in jqgrid.
The data set is returned to the client with each item having a list of designers:
"IAConsultWorkflowRequestsList": [
{
"AppID": "ISP",
"SubmittedDate": "12/13/2018",
"IAAssigned": "<a style='color:blue !important;' href='mailto:Joseph#somewhere.com'><u>Joseph Kraft</u></a>",
"IAAssignedName": null,
"Status": "In Discovery",
"SLA": 0,
"DaysPassed": 157,
"IsUserFM": false,
"IsUserSecureEnv": false,
"DesignParticipants": [
{
"Name": "John Kraft",
"EmailAddress": "",
"ID": "A2049"
},
{
"Name": "Zack Adamas",
"EmailAddress": "Zachary.Adamas#somewhere.com",
"ID": "U6696"
},
{
"Name": "David Kosov",
"EmailAddress": "David.Kosov#somewhere.com",
"ID": "U6644"
}
]
}
So in the 'Designers' column, I am concatenating the results to be comma separated, e.g.
John Kraft,
Zack Adamas,
David Kosov
And, if the item has an email address, the individual name is formatted as an email link:
<td role="gridcell" style="text-align:center;" title="John Kraft,Zack Burns,David Cosand" aria-describedby="workFlowIAGrid_DesignParticipants">
John Kraft,<br>
<a style="color:blue !important;" ref="mailto:Zachary#somewhere.com"><u>Zack </u></a>,<br>
<a style="color:blue !important;" href="mailto:David#somewhere.com"><u>David </u></a></td>
I have a select element with entries John, Zack, and David, but when I select one of the options, I do not get expected results. If I select David, I would like to be shown any rows that contain David as one of potentially several names in the Designer column.
However, I am getting erratic behavior. Some of the sopt options will cause something to happen, but not what is expected. None of the contains/not contained or in/not in options seem to do what I need. What am I doing wrong?
Per Tony's comment, here is the grid init code:
$gridEl.jqGrid({
xhrFields: {
cors: false
},
url: "/IAConsult/GetWorkFlowIARequests",
postData: {
showAll: showAllVal,
role: role,
IsIAArchitect: userIsIA
},
datatype: "json",
crossDomain: true,
loadonce: true,
mtype: 'GET',
sortable: true,
viewrecords: true,
pager: '#workFlowIAGridPager',
multiselect: true,
rowNum: 50,
autowidth: true,
colModel: [
{ label: 'Design Participants', name: 'DesignParticipants', align: "center", formatter:commaSeparatedList },
//same for other columns...
],
beforeSelectRow: function (rowid, e) {
var $myGrid = $(this),
i = $.jgrid.getCellIndex($(e.target).closest('td')[0]),
cm = $myGrid.jqGrid('getGridParam', 'colModel');
return (cm[i].name === 'cb');
},
jsonReader: {
repeatitems: true,
root: "IAConsultWorkflowRequestsList"
},
beforeSubmitCell: function (rowid, name, value, iRow, iCol) {
return {
gridData: gridData
};
},
serializeCellData: function (postdata) {
return JSON.stringify(postdata);
},
gridComplete: function () {
rowCount = $gridEl.getGridParam('records');
gridViewRowCount = rowCount;
var rowIDs = $gridEl.getDataIDs();
var inCompleteFlag = false;
//Filter code to apply filter in headers in MyWork grid
var datatoFilter = $gridEl.jqGrid('getGridParam', 'lastSelectedData').length == 0
? $gridEl.jqGrid("getGridParam", "data")
: $gridEl.jqGrid('getGridParam', 'lastSelectedData');
var $grid = $gridEl, postfilt = "";
var getUniqueNames = function (columnName) {
var uniqueTexts = [],
mydata = datatoFilter,
texts = $.map(mydata, function(item) {
return item[columnName];
}),
textsLength = texts.length,
text = "",
textsMap = {},
i;
if (texts[0] && texts[0].Name)
texts = $.map(texts,
function(item) {
return item.Name;
});
for (i = 0; i < textsLength; i++) {
text = texts[i];
if (text !== undefined && textsMap[text] === undefined) {
// to test whether the texts is unique we place it in the map.
textsMap[text] = true;
uniqueTexts.push(text);
}
}
if (columnName == 'ConsultID') {
return (uniqueTexts.sort(function (a, b) { return a - b; }));
} else return uniqueTexts.sort();
}, buildSearchSelect = function (uniqueNames) {
var values = {};
values[''] = 'All';
$.each(uniqueNames,
function () {
values[this] = this;
});
return values;
}, setSearchSelect = function (columnName) {
var changedColumns = [];
this.jqGrid("setColProp",
columnName,
{
stype: "select",
searchoptions: {
value: buildSearchSelect(getUniqueNames.call(this, columnName)),
sopt: getSortOptionsByColName(columnName),
dataEvents: [
{
type: "change",
fn: function (e) {
setTimeout(function () {
//get values of dropdowns
var DesignParticipant = $('#gs_workFlowIAGrid_DesignParticipants').val();
//same for other columns...
var columnNamesArr = columns.split(',');
changedColumns.push(columnName);
for (i = 0; i < columnNamesArr.length; i++) {
if (true) {
var htmlForSelect = '<option value="">All</option>';
var un = getUniqueNames(columnNamesArr[i]);
var $select = $("select[id='gs_workFlowIAGrid_" + columnNamesArr[i] + "']");
for (j = 0; j < un.length; j++) {
var val = un[j];
htmlForSelect += '<option value="' + val + '">' + val + '</option>';
}
$select.find('option').remove().end().append(htmlForSelect);
}
}
$('#gs_workFlowIAGrid_DesignParticipants').val(DesignParticipant);
//same for other columns...
},
500);
//setting the values :
}
}
]
}
});
};
function getSortOptionsByColName(colName) {
console.log(colName);
if (colName === 'DesignParticipants')
return ['in'];
else
return ['eq'];
}
setSearchSelect.call($grid, "DesignParticipants");
//same for other columns...
$grid.jqGrid("filterToolbar",
{ stringResult: true, searchOnEnter: true });
var localFilter = $gridEl.jqGrid('getGridParam', 'postData').filters;
if (localFilter !== "" && localFilter != undefined) {
globalFilter = localFilter;
}
$gridEl.jqGrid("setGridParam",
{
postData: {
"filters": globalFilter,
showAll: showAllVal,
role: role,
IsIAArchitect: userIsIA
},
search: true,
forceClientSorting: true
})
.trigger("reloadGrid");
//Ending Filter code
var columnNamesArr = columns.split(',');
for (i = 0; i < columnNamesArr.length; i++) {
if (true) {
var htmlForSelect = '<option value="">All</option>';
var un = getUniqueNames(columnNamesArr[i]);
var $select = $("select[id='gs_workFlowIAGrid_" + columnNamesArr[i] + "']");
for (j = 0; j < un.length; j++) {
val = un[j];
htmlForSelect += '<option value="' + val + '">' + val + '</option>';
}
$select.find('option').remove().end().append(htmlForSelect);
}
}
},
// all grid parameters and additionally the following
loadComplete: function () {
$gridEl.jqGrid('setGridWidth', $(window).width(), true);
$gridEl.setGridWidth(window.innerWidth - 20);
},
height: '100%'
});
Here is the formatter I am using on the column:
function commaSeparatedList(cellValue, options, rowdata, action) {
let dps = [];
_.forEach(cellValue, function (item) {
let formatted = '';
if (item.EmailAddress)
formatted += '<a style="color:blue !important;" href="mailto:' +
item.EmailAddress +
'"><u>' +
item.Name +
'</u></a>';
else formatted = item.Name;
dps.push(formatted + ',<br/>');
});
let toString = dps.join('');
return toString.substring(0,toString.length-6);
}
And then the only other pertinent thing is that I used a function to return 'in' (or some other key - these are the options I said weren't apparently working in the initial post) if the column is named 'Design Participants', else equal for any other column:
setSearchSelect = function (columnName) {
var changedColumns = [];
this.jqGrid("setColProp",
columnName,
{
stype: "select",
searchoptions: {
value: buildSearchSelect(getUniqueNames.call(this, columnName)),
sopt: getSortOptionsByColName(columnName),
dataEvents: [
{...
function getSortOptionsByColName(colName) {
console.log(colName);
if (colName === 'DesignParticipants')
return ['in'];
else
return ['eq'];
}
The issue was that the underlying data (the DesignParticipants in the returned JSON above) did not match the selected string, since the data itself was an array. I believed the filtering was based on the displayed text in the grid table, but, it was based on the underlying data. So, I created a new property of the returned JSON that was a string, and the filtering worked as expected.
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.
I am working on a site that uses the Simile Timeline. I am using Kendo Core for the single page application components. I am loading the timeline from the results of an ajax request. I am manually adding the events. When I check the console the events are populated on the event source. However events do not display.
What do I need to change to get the events to display on the timeline?
Thanks in advance.
///////////////////////////////
// Timeline
///////////////////////////////
var timelineViewModel = kendo.observable({
InitUI: function (id) {
var self = this;
$.ajax({
url: "api/timelines/" + id,
type: "GET",
dataType: "json",
contentType: "application/json",
success: function (data) {
self.loadTimeLine(data);
}
});
},
loadTimeLine: function (data) {
SimileAjax.History.enabled = false;
$('#TimelineTitle').text(data.title);
var tl_el = document.getElementById("my-timeline");
var eventSource1 = new Timeline.DefaultEventSource();
for(var eIndex = 0; eIndex < data.events.length; eIndex ++)
{
var evt = new Timeline.DefaultEventSource.Event({
title: data.events[eIndex].title,
start: data.events[eIndex].start,
description: data.events[eIndex].description,
caption: data.events[eIndex].title,
color: '#FFCC33',
text: data.events[eIndex].title
});
eventSource1._events.add(evt);
}
var theme1 = Timeline.ClassicTheme.create();
theme1.event.bubble.width = 320;
theme1.event.bubble.height = 220;
var d = data.MinDate;
var bandInfos = [
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.YEAR,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.MONTH,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 350, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.WEEK,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'original'
})
];
bandInfos[1].syncWith = 2;
bandInfos[1].highlight = true;
bandInfos[0].syncWith = 2;
bandInfos[0].highlight = true;
tl = Timeline.create(tl_el, bandInfos, Timeline.VERTICAL);
tl.layout();
}
})
var timelineView = new kendo.View(
"timelineTemplate",
{
model: timelineViewModel
}
);
///////////////////////////////
// Layout
///////////////////////////////
var layout = new kendo.Layout("<div id='content'></div>");
///////////////////////////////
// DAS ROUTER
///////////////////////////////
var router = new kendo.Router();
router.route("(:viewName)/(:id)", function (viewName, id) {
layout.render("#maincontent");
if (viewName) {
switch (viewName.toLowerCase()) {
case "timeline":
if (id) {
if (id.toLowerCase() == "new") {
layout.showIn("#content", createTimelineView);
createTimelineViewModel.InitUI();
}
else {
layout.showIn("#content", timelineView);
timelineViewModel.InitUI(id);
}
}
break;
case "account":
if (id) {
layout.showIn("#content", accountView);
accountViewModel.InitUI(id);
}
break;
}
}
else {
layout.showIn("#content", indexView);
indexViewModel.InitUI();
}
});
$(function () {
router.start();
});
I'm looking to add on to the kendoValidator required rule. I want it to function the same way but with one exception. Unfortunately once I provide a function for it in the rules section I have to code all the logic for the required function again.
wondering if there is a way to piggyback off the existing functionality of "required" rule. Currently the code below has everything marked required that isn't disabled, even if it has a value in it.
function runValidation() {
$(".dateTimePickerField").each(function () {
var validator = $(this).kendoValidator({
rules: {
required: function (e) {
if ($(e).is(':disabled'))
{
return true;
}
},
dateValidation: function (e) {
var dateTime = $(e).val();
var currentDate = Date.parse($(e).val());
if (dateTime.length > 0 && !currentDate) {
return false;
}
return true;
}
},
messages: {
//Define your custom validation massages
required: "datetime required",
dateValidation: "Invalid datetime"
}
}).data("kendoValidator");
validator.validate();
});
}
I just ended up coding the necessary logic for the required rule. It wasn't too difficult of a rule to code so i just did that.
function runValidation() {
var boolval = true;
$("input.dateTimePickerField").each(function () {
var validator = $(this).kendoValidator({
rules: {
required: function (e) {
if ($(e).prop('required')) {
if ($(e).is(':disabled') || $(e).val().length > 0) {
return true;
}
return false;
}
return true;
},
dateValidation: function (e) {
var dateTime = $(e).val();
var currentDate = Date.parse($(e).val());
if (dateTime.length > 0 && !currentDate) {
return false;
}
return true;
},
customEventDateValidation: function (e) {
var dateTime = $(e).val();
var currentDate = Date.parse($(e).val());
var row = $(e).closest('tr');
var startDateText = row.find(".startDate").text();
var eventStartDate = Date.parse(startDateText);
if (currentDate && eventStartDate)
{
if(currentDate > eventStartDate)
{
return false;
}
}
return true;
},
customTicketStartDateValidation: function (e) {
if ($(e).hasClass("ticketStartDate"))
{
var dateTime = $(e).val();
var currentDate = Date.parse($(e).val());
var row = $(e).closest('tr');
var ticketEndDateText = row.find("input.ticketEndDate").val();
var ticketEndDate = Date.parse(ticketEndDateText);
if(currentDate && ticketEndDate)
{
if(currentDate > ticketEndDate)
{
return false;
}
}
}
return true;
},
customTicketEndDateValidation: function (e) {
if ($(e).hasClass("ticketEndDate")) {
var dateTime = $(e).val();
var currentDate = Date.parse($(e).val());
var row = $(e).closest('tr');
var ticketStartDateText = row.find("input.ticketStartDate").val();
var ticketStartDate = Date.parse(ticketStartDateText);
if (currentDate && ticketStartDate) {
if (currentDate < ticketStartDate) {
return false;
}
}
}
return true;
}
},
messages: {
required: "Datetime required",
dateValidation: "Invalid datetime",
customEventDateValidation: "Datetime must be before event date",
customTicketStartDateValidation: "Ticket start datetime must be before ticket end datetime",
customTicketEndDateValidation: "Ticket end datetime must be after ticket start datetime"
}
}).data("kendoValidator");
if (!validator.validate()) {
boolval = false;
}
});
return boolval;
}
I am trying to implement a Firefox Extension which modify the POST request data.
Code follows, it fails where marked "Fails here!!!"
Any insight would be helpful.
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var newData = "test 123";
function LOG(msg) {
var consoleService = Components.classes["#mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage(msg);
}
function CMP() {
this.registered = false;
this.register();
}
CMP.prototype = {
register: function() {
if (this.registered == false) {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "http-on-modify-request", false);
this.registered = true;
}
},
observe: function(subject, topic, data)
{
LOG("Inside observe");
if (topic == "http-on-modify-request")
{
LOG("TOPIC is http-on-modify-request");
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST"){
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
//var uploadChannelStream = uploadChannel.uploadStream;
Modify the data here. Here for testing i am passing "test 123" as new data
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
LOG("set data in newStringInputStream!!");
uploadChannel.setUploadStream(newStringInputStream, "text/plain", -1 );// Fails here!!!
httpChannel.requestMethod = "POST";
LOG("upload DONE!!")
}
}
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
},
unregister: function() {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
},
classID: Components.ID('{F799F47E-ABA5-4AF1-B8F2-BD74E3E5BCC0}'),
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver])
};
if (XPCOMUtils.generateNSGetFactory)
{
var NSGetFactory = XPCOMUtils.generateNSGetFactory([CMP]);
}
Fixed it by changing by following in the above code. Main change was in setting modified data in httpChannel.uploadStream.
Hope this helps someone!
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST")
{
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
var uploadChannelStream = uploadChannel.uploadStream;
uploadChannelStream = uploadChannelStream.QueryInterface(Components.interfaces.nsISeekableStream).seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
httpChannel.uploadStream.QueryInterface(Components.interfaces.nsIMIMEInputStream);
httpChannel.uploadStream.setData(newStringInputStream);
LOG("Done POST")
}