jsharmony-cms
Version:
1,163 lines (1,016 loc) • 47.8 kB
JavaScript
jsh.App[modelid] = new (function(){
var _this = this;
this.revision_page_key = undefined;
this.revision_page_id = undefined;
this.sitemap_key = null;
this.sitemap_id = null;
this.sitemap_items = [];
this.selected_sitemap_item_id = null;
this.loadobj = {};
this.has_changes = false;
this.first_render = true;
this.sitemap_item_base = {
sitemap_item_id: undefined,
sitemap_item_parent_id: null,
sitemap_item_path: undefined,
sitemap_item_depth: undefined,
sitemap_item_seq: undefined,
sitemap_item_text: '',
sitemap_item_type: 'TEXT', //TEXT(default),HTML
sitemap_item_tag: undefined,
sitemap_item_style: undefined,
sitemap_item_class: undefined,
sitemap_item_exclude_from_breadcrumbs: 0,
sitemap_item_exclude_from_parent_menu: 0,
sitemap_item_hide_menu_parents: 0,
sitemap_item_hide_menu_siblings: 0,
sitemap_item_hide_menu_children: 0,
sitemap_item_link_type: undefined, //PAGE,MEDIA,URL,JS
sitemap_item_link_dest: undefined,
sitemap_item_link_page: undefined,
sitemap_item_link_media: undefined,
sitemap_item_link_target: undefined, //NEWWIN
};
this.orig_current_sitemap_item = null;
this.oninit = function(){
jsh.System.applyRoles();
if(jsh._GET.sitemap_id) {
this.sitemap_id = jsh._GET.sitemap_id;
} else {
jsh.System.RequireBranch(xmodel);
}
jsh.on('jsh_message', function(event, data){ _this.onmessage(data); });
this.sitemap_key = jsh._GET.sitemap_key;
$(window).bind('resize', _this.onresize);
_this.refreshLayout();
xmodel.controller.HasUpdates = function(){ return _this.hasUpdates(); };
var jtree = jsh.$root('.xelem'+xmodel.class+'.sitemap_item_id');
jtree.data('ondoubleclick', jsh._instance+'.App['+JSON.stringify(xmodel.id)+'].sitemap_item_id_ondoubleclick(n);');
};
this.ondestroy = function(xmodel){
$(window).unbind('resize', _this.onresize);
};
this.onload = function(){
var bcrumbs = jsh.XPage.getBreadcrumbs();
_this.refreshLayout();
_this.getSitemap();
jsh.System.renderEditorSelection(xmodel.controller.getLOV('site_editor'), bcrumbs.site_id, bcrumbs.sys_user_site_editor, { after: jsh.$root('.bcrumbs_branch_body'), containerClass: 'bcrumbs_editor_selection_container' });
};
this.onresize = function(){ _this.refreshLayout(); };
this.refreshLayout = function(){
var jbrowser = $('.'+xmodel.class+'_browser');
if(!jbrowser.length) return;
var wh = $(window).height();
var top = jbrowser.offset().top;
var contentheight = wh - top - 20;
$('.'+xmodel.class+'_browser').css('height',contentheight+'px');
};
this.hasUpdates = function(){
_this.checkUpdatesInfo();
return _this.has_changes;
};
this.setDirty = function(isDirty){
_this.has_changes = isDirty;
jsh.$root('.xelem'+xmodel.class+'.xform_button_saveSitemap').toggleClass('hasChanges', isDirty);
};
this.onmessage = function(data){
data = (data || '').toString();
if(data.indexOf('jsharmony-cms:refresh_page_key:')==0){
var refresh_page_key = data.substr(31);
var xmodelInfo = _this.getModelInfo();
var cur_sitemap_item_link_type = xmodelInfo.get('sitemap_item_link_type');
var cur_sitemap_item_link_dest = xmodelInfo.get('sitemap_item_link_dest');
if((cur_sitemap_item_link_type == 'PAGE') && ((cur_sitemap_item_link_dest||'').toString() == refresh_page_key)){
jsh.App[xmodelInfo.id].updatePageInfo(true);
}
}
};
this.sitemap_item_id_onchange = function(obj, newval, undoChange, e) {
if(_this.selected_sitemap_item_id && !_this.commitInfo()){
return undoChange();
}
this.selectSitemapItem(newval);
};
this.dragHoveringTop = 0;
this.dragHoveringBottom = 0;
this.sitemap_item_id_onmove = function(dragval, dropval, anchor, e) {
if(!XExt.hasAction(xmodel.actions,'U')) return;
if(!dragval || !dropval) return;
if(dragval=='ROOT') return XExt.Alert('Cannot move root node');
var dragitem = _this.getSitemapItem(dragval);
if(!dragitem) return;
var prev_dropitemidx = -1;
var dropitemidx = -1;
var dragitemidx = _.indexOf(_this.sitemap_items, dragitem);
var prev_dragitemidx = dragitemidx;
var prev_parent_id = dragitem.sitemap_item_parent_id;
if(dropval=='ROOT'){
//Drop on root
_this.sitemap_items.splice(dragitemidx, 1);
dragitem.sitemap_item_parent_id = null;
_this.sitemap_items.splice(0, 0, dragitem);
//Check if any move was actually performed
dragitemidx = _.indexOf(_this.sitemap_items, dragitem);
}
else {
//Drop on another item
var dropitem = _this.getSitemapItem(dropval);
if(!dropitem) return;
if(dragitem == dropitem) return;
prev_dropitemidx = _.indexOf(_this.sitemap_items, dropitem);
_this.sitemap_items.splice(dragitemidx, 1);
dropitemidx = _.indexOf(_this.sitemap_items, dropitem);
//Move node, based on anchor
if(anchor[1] == 'full'){
dragitem.sitemap_item_parent_id = dropitem.sitemap_item_id;
_this.sitemap_items.splice(dropitemidx + 1, 0, dragitem);
}
else if(anchor[1] == 'top'){
dragitem.sitemap_item_parent_id = dropitem.sitemap_item_parent_id;
_this.sitemap_items.splice(dropitemidx, 0, dragitem);
}
else if(anchor[1] == 'bottom'){
dragitem.sitemap_item_parent_id = dropitem.sitemap_item_parent_id;
_this.sitemap_items.splice(dropitemidx + 1, 0, dragitem);
}
//Check if any move was actually performed
dragitemidx = _.indexOf(_this.sitemap_items, dragitem);
dropitemidx = _.indexOf(_this.sitemap_items, dropitem);
}
if((dragitemidx==prev_dragitemidx)&&(dropitemidx==prev_dropitemidx)&&(prev_parent_id==dragitem.sitemap_item_parent_id)){
/* No Changes */
}
else{
_this.setDirty(true);
_this.parseSitemap();
_this.renderSitemap();
_this.selectSitemapItem(_this.selected_sitemap_item_id, { softSave: true });
}
};
this.sitemap_item_id_context_menu_onrender = function(sitemap_item_id, action, obj){
if(action=='delete'){
return (sitemap_item_id != 'ROOT');
}
else if((action=='page')||(action=='edit')){
sitemap_item_id = parseInt(sitemap_item_id);
var sitemap_item = _this.getSitemapItem(sitemap_item_id);
if(!sitemap_item) return false;
if(sitemap_item.sitemap_item_link_type=='PAGE'){
var page_key = sitemap_item.sitemap_item_link_dest;
if(page_key){
if(action=='edit'){
//Update URL
$(obj).off('.sitemap_load_url').on('mousedown.sitemap_load_url', function(e){
var jobj = $(this);
//Right click
if(e.which==3){
//Resolve URL
_this.getEditorURL(page_key, function(url){
jobj.attr('href', url || '#');
});
}
});
}
return true;
}
}
return false;
}
else if(action=='add_home'){
if(sitemap_item_id !== 'ROOT') return false;
}
};
this.sitemap_item_id_ondoubleclick = function(sitemap_item_id){
sitemap_item_id = parseInt(sitemap_item_id);
var sitemap_item = _this.getSitemapItem(sitemap_item_id);
if(!sitemap_item) return false;
if(sitemap_item.sitemap_item_link_type=='PAGE'){
var page_key = sitemap_item.sitemap_item_link_dest;
if(page_key) _this.editPageContent(page_key);
}
};
this.getSitemap = function(){
if(!_this.sitemap_key){ XExt.Alert('Missing sitemap key'); return; }
var url = '../_funcs/sitemap/'+_this.sitemap_key;
if(_this.sitemap_id){
url += '?sitemap_id=' + _this.sitemap_id;
if(jsh._GET.branch_id) url += '&branch_id='+jsh._GET.branch_id;
}
XExt.CallAppFunc(url, 'get', { }, function (rslt) { //On Success
if ('_success' in rslt) {
_this.parseSitemap(rslt.sitemap);
_this.renderSitemap();
_this.selectSitemapItem(_this.getFirstSitemapItemID());
}
else{
XExt.Alert('Error loading sitemap');
}
}, function (err) {
});
};
this.getFirstSitemapItemID = function(){
var rslt = jsh.$root('.sitemap_item_id.xelem'+xmodel.class).find('.tree_item').first().data('value');
return rslt||null;
};
this.getPrevSitemapItemID = function(sitemap_item_id){
var sitemap_item_ids = _.map(jsh.$root('.sitemap_item_id.xelem'+xmodel.class).find('.tree_item'), function(obj){ return parseInt(obj.getAttribute('data-value')); });
for(var i=0;i<sitemap_item_ids.length;i++){
if(sitemap_item_ids[i]==sitemap_item_id){
if(i==0) return null;
return sitemap_item_ids[i-1];
}
}
return null;
};
this.parseSitemap = function(sitemap){
if(sitemap){
var sitemap_items = [];
if(sitemap && sitemap.sitemap_items) sitemap_items = sitemap.sitemap_items;
_this.sitemap_items = sitemap_items;
}
_this.regenerateSitemap();
_this.generateSitemapLOV();
};
this.regenerateSitemap = function(){
//Validate IDs
var sitemap_item_ids = [];
for(let i=0;i<_this.sitemap_items.length;i++){
let sitemap_item = _this.sitemap_items[i];
sitemap_item.sitemap_item_seq = i+1;
if(!sitemap_item.sitemap_item_id) return XExt.Alert('Missing sitemap item ID');
var prev_sitemap_item_id = sitemap_item.sitemap_item_id;
sitemap_item.sitemap_item_id = parseInt(sitemap_item.sitemap_item_id);
if(prev_sitemap_item_id.toString() != sitemap_item.sitemap_item_id.toString()) return XExt.Alert('Invalid sitemap item ID: '+prev_sitemap_item_id.toString());
if(sitemap_item.sitemap_item_id in sitemap_item_ids) return XExt.Alert('Duplicate sitemap item ID: '+prev_sitemap_item_id.toString());
sitemap_item_ids[sitemap_item.sitemap_item_id] = sitemap_item;
}
//Validate Parent ID's, Reset Paths
for(let i=0;i<_this.sitemap_items.length;i++){
let sitemap_item = _this.sitemap_items[i];
var prev_sitemap_item_parent_id = sitemap_item.sitemap_item_parent_id;
if(!prev_sitemap_item_parent_id){
sitemap_item.sitemap_item_parent_id = null;
sitemap_item.sitemap_item_path = '/' + sitemap_item.sitemap_item_id.toString() + '/';
sitemap_item.sitemap_item_depth = 1;
}
else {
sitemap_item.sitemap_item_parent_id = parseInt(sitemap_item.sitemap_item_parent_id);
if(prev_sitemap_item_parent_id.toString() != sitemap_item.sitemap_item_parent_id.toString()) return XExt.Alert('Invalid parent sitemap item ID: '+prev_sitemap_item_parent_id.toString());
if(!(sitemap_item.sitemap_item_parent_id in sitemap_item_ids)) return XExt.Alert('Invalid parent sitemap item ID: '+prev_sitemap_item_id.toString());
sitemap_item.sitemap_item_path = null;
}
}
//Generate paths
var getSitemapItemPath = function(sitemap_item){
if(!sitemap_item.sitemap_item_path){
var sitemap_item_parent = sitemap_item_ids[sitemap_item.sitemap_item_parent_id];
sitemap_item.sitemap_item_path = getSitemapItemPath(sitemap_item_parent) + sitemap_item.sitemap_item_id.toString() + '/';
sitemap_item.sitemap_item_depth = sitemap_item_parent.sitemap_item_depth + 1;
}
return sitemap_item.sitemap_item_path;
};
for(let i=0;i<_this.sitemap_items.length;i++){
getSitemapItemPath(_this.sitemap_items[i]);
}
_this.sitemap_items.sort(function(a,b){
if(a.sitemap_item_depth > b.sitemap_item_depth) return 1;
if(a.sitemap_item_depth < b.sitemap_item_depth) return -1;
if(a.sitemap_item_seq > b.sitemap_item_seq) return 1;
if(a.sitemap_item_seq < b.sitemap_item_seq) return -1;
return 0;
});
for(let i=0;i<_this.sitemap_items.length;i++){
_this.sitemap_items[i].sitemap_item_seq = i+1;
}
};
this.generateSitemapLOV = function(){
var lov = [];
var root_item = {};
root_item[jsh.uimap.code_id] = 'ROOT';
root_item[jsh.uimap.code_parent_id] = null;
root_item[jsh.uimap.code_val] = 'ROOT';
root_item[jsh.uimap.code_txt] = '(Root)';
root_item[jsh.uimap.code_icon] = 'folder';
lov.push(root_item);
var sitemap_parent_ids = {};
_.each(_this.sitemap_items, function(sitemap_item){ sitemap_parent_ids[sitemap_item.sitemap_item_parent_id||'ROOT'] = true; });
_.each(_this.sitemap_items, function(sitemap_item){
var lov_item = {};
lov_item[jsh.uimap.code_id] = sitemap_item.sitemap_item_id;
lov_item[jsh.uimap.code_parent_id] = sitemap_item.sitemap_item_parent_id||'ROOT';
lov_item[jsh.uimap.code_val] = sitemap_item.sitemap_item_id;
lov_item[jsh.uimap.code_txt] = (XExt.StripTags(sitemap_item.sitemap_item_text)||'').trim();
lov_item[jsh.uimap.code_icon] = (sitemap_parent_ids[sitemap_item.sitemap_item_id] ? 'folder' : 'file');
lov.push(lov_item);
});
if(!xmodel.controller.form.Data._LOVs) xmodel.controller.form.Data._LOVs = {};
xmodel.controller.form.Data._LOVs.sitemap_item_id = lov;
};
this.renderSitemap = function(){
//Render Tree
xmodel.controller.form.Render();
//Expand first node on initial render
if(_this.first_render){
XExt.TreeExpandNode($('.xelem'+xmodel.class+'.sitemap_item_id.tree'),'ROOT');
}
//Select current item in tree
if(_this.selected_sitemap_item_id){
xmodel.set('sitemap_item_id', _this.selected_sitemap_item_id);
}
};
this.getSitemapItem = function(sitemap_item_id){
if(!sitemap_item_id) return null;
sitemap_item_id = parseInt(sitemap_item_id);
for(var i=0;i<_this.sitemap_items.length;i++){
if(_this.sitemap_items[i].sitemap_item_id===sitemap_item_id) return _this.sitemap_items[i];
}
return null;
};
this.selectSitemapItem = function(sitemap_item_id, options){
options = _.extend({ softSave: false }, options);
sitemap_item_id = parseInt(sitemap_item_id || 0);
if(!sitemap_item_id){
jsh.$root('.xsubform.Sitemap_Tree_Info').hide();
_this.selected_sitemap_item_id = null;
_this.save({ softSave: true });
return;
}
else {
if(xmodel.get('sitemap_item_id') != sitemap_item_id){
xmodel.set('sitemap_item_id', sitemap_item_id);
return;
}
jsh.$root('.xsubform.Sitemap_Tree_Info').show();
if(_this.selected_sitemap_item_id == sitemap_item_id){
if(options.softSave) _this.save({ softSave: true });
return;
}
_this.selected_sitemap_item_id = sitemap_item_id;
}
var sitemap_item = _.extend({}, _this.sitemap_item_base, _this.getSitemapItem(sitemap_item_id));
if(!sitemap_item){ XExt.Alert('Sitemap item '+sitemap_item_id+' not found'); return; }
var modelInfo = _this.getModelInfo();
var xformInfo = modelInfo.controller.form;
var xdataInfo = xformInfo.Data;
xdataInfo = _.extend(xdataInfo,sitemap_item);
xdataInfo._is_insert = false;
xdataInfo._is_dirty = false;
xdataInfo._is_deleted = false;
xdataInfo._orig = null;
xformInfo.Render();
_this.orig_current_sitemap_item = _.extend({}, xdataInfo);
jsh.App[modelInfo.id].onload();
_this.save({ softSave: true });
};
this.getModelInfo = function(){
return jsh.XModels[jsh.XBase[xmodel.namespace+'Sitemap_Tree_Info'][0]];
};
this.checkUpdatesInfo = function(){
if(!_this.selected_sitemap_item_id) return true;
var xmodelInfo = _this.getModelInfo();
_.each([
'sitemap_item_type',
'sitemap_item_text',
'sitemap_item_link_type',
'sitemap_item_link_target',
'sitemap_item_link_dest',
'sitemap_item_class',
'sitemap_item_style',
'sitemap_item_exclude_from_breadcrumbs',
'sitemap_item_exclude_from_parent_menu',
'sitemap_item_hide_menu_parents',
'sitemap_item_hide_menu_siblings',
'sitemap_item_hide_menu_children',
'sitemap_item_tag'
], function(key){
var oldval = _this.orig_current_sitemap_item[key];
if(XExt.isNullUndefined(oldval)) oldval = '';
oldval = oldval.toString();
var newval = xmodelInfo.get(key);
if(XExt.isNullUndefined(newval)) newval = '';
newval = newval.toString();
if(oldval != newval){
_this.setDirty(true);
}
});
};
this.commitInfo = function(){
if(!_this.selected_sitemap_item_id) return true;
_this.checkUpdatesInfo();
var xdataInfo = _this.getModelInfo().controller.form.Data;
if(!xdataInfo.Commit('B')) return false;
var sitemap_item = _this.getSitemapItem(_this.selected_sitemap_item_id);
if(!sitemap_item) return XExt.Alert('Sitemap item not found for ID: '+_this.selected_sitemap_item_id);
var rerender = (_this.orig_current_sitemap_item.sitemap_item_text != xdataInfo.sitemap_item_text);
_.each([
'sitemap_item_type',
'sitemap_item_text',
'sitemap_item_link_type',
'sitemap_item_link_target',
'sitemap_item_link_dest',
'sitemap_item_link_page',
'sitemap_item_link_media',
'sitemap_item_class',
'sitemap_item_style',
'sitemap_item_exclude_from_breadcrumbs',
'sitemap_item_exclude_from_parent_menu',
'sitemap_item_hide_menu_parents',
'sitemap_item_hide_menu_siblings',
'sitemap_item_hide_menu_children',
'sitemap_item_tag'
], function(key){
if(key in xdataInfo){
sitemap_item[key] = xdataInfo[key];
}
});
_this.orig_current_sitemap_item = _.extend({}, xdataInfo);
if(rerender){
_this.parseSitemap();
_this.renderSitemap();
}
return true;
};
this.deleteSitemapItem = function(sitemap_item_id, force){
sitemap_item_id = parseInt(sitemap_item_id);
var sitemap_item = _this.getSitemapItem(sitemap_item_id);
if(!sitemap_item){ XExt.Alert('Invalid sitemap item ID'); return; }
//Find children
var sitemap_item_children = [];
for(let i=0;i<_this.sitemap_items.length;i++){
if(_this.sitemap_items[i].sitemap_item_parent_id==sitemap_item.sitemap_item_id){
sitemap_item_children.push(_this.sitemap_items[i].sitemap_item_id);
}
}
if(!force){
XExt.Confirm('Are you sure you want to delete sitemap item "'+sitemap_item.sitemap_item_text+'"'+(sitemap_item_children.length?' and all of its children':'')+'?', function (rslt) {
var next_sitemap_item_id = _this.selected_sitemap_item_id;
if(next_sitemap_item_id == sitemap_item_id) next_sitemap_item_id = _this.getPrevSitemapItemID(sitemap_item_id);
var deletedPages = _this.deleteSitemapItem(sitemap_item_id, true)||[];
XExt.execif(deletedPages.length, function(f){
//Confirm whether to delete the pages from the system
var msg = "<div style='text-align:left;'>";
msg += 'Permanently delete the following pages from the site?';
for(let i = 0; i < deletedPages.length; i++){ msg += '<br/>' + deletedPages[i].page_path; }
msg += '</div>';
XExt.Confirm(msg, function(){
//Delete the pages
var deleteErrors = [];
async.eachSeries(deletedPages, function(page, page_cb){
XForm.Delete(xmodel.module_namespace+'Page_Tree_Listing', { page_key: page.page_key }, { }, function(rslt){ //On Success
return page_cb();
}, undefined, { OnDBError: function(err){ //On Error
if(err){
var errmsg = 'Error deleting '+page.page_path+' - ';
if(err.Number && (err.Number == -3)) errmsg += 'Page not found';
else if(err.Message) errmsg += err.Message;
else errmsg += err.toString();
deleteErrors.push(errmsg);
}
page_cb();
return false;
} });
}, function(err){
if(err) deleteErrors.push(err.toString());
if(deleteErrors.length) XExt.Alert(deleteErrors.join('\n'), f);
else f();
});
}, f, { message_type: 'html' });
}, function(){
//Reload sitemap and select previous node
_this.parseSitemap();
_this.renderSitemap();
if(!next_sitemap_item_id || !_this.getSitemapItem(next_sitemap_item_id)) next_sitemap_item_id = _this.getFirstSitemapItemID();
_this.selected_sitemap_item_id = null;
_this.selectSitemapItem(next_sitemap_item_id);
});
});
return;
}
var deletedPages = [];
if(sitemap_item.sitemap_item_link_type=='PAGE'){
var page_key = sitemap_item.sitemap_item_link_dest;
var page_path = sitemap_item.sitemap_item_link_page;
if(!page_path) page_path = 'Page #' + page_key;
if(page_path == 'PAGE :: '+(page_key||'').toString()+' :: Not found'){ /* Do nothing */ }
else deletedPages.push({ page_key: page_key, page_path: page_path });
}
_.each(sitemap_item_children, function(sitemap_item_id){
var deletedChildPages = _this.deleteSitemapItem(sitemap_item_id, true);
for(let i=0; i < deletedChildPages.length; i++) deletedPages.push(deletedChildPages[i]);
});
//Delete item
for(let i=0;i<_this.sitemap_items.length;i++){
if(_this.sitemap_items[i]==sitemap_item){
_this.sitemap_items.splice(i,1);
i--;
}
}
_this.setDirty(true);
return deletedPages;
};
this.getSitemapItemParentID = function(sitemap_item_id){
if(!_this.commitInfo()) return;
sitemap_item_id = parseInt(sitemap_item_id);
var sitemap_item = _this.getSitemapItem(sitemap_item_id);
if(!sitemap_item){ XExt.Alert('Invalid sitemap item ID'); return; }
return sitemap_item.sitemap_item_parent_id;
};
this.getSitemapItemPageKey = function(sitemap_item_id, f){
if(!_this.commitInfo()) return;
sitemap_item_id = parseInt(sitemap_item_id);
var sitemap_item = _this.getSitemapItem(sitemap_item_id);
if(!sitemap_item){ XExt.Alert('Invalid sitemap item ID'); return; }
//Find children
if(sitemap_item.sitemap_item_link_type!='PAGE'){ XExt.Alert('Sitemap item does not link to a page'); return; }
var page_key = parseInt(sitemap_item.sitemap_item_link_dest);
if(!page_key){ XExt.Alert('Sitemap item does not link to a valid page'); return; }
if(f) f(page_key);
return page_key;
};
this.getDefaultPage = function(){
return jsh.XPage.getBreadcrumbs().site_default_page_filename;
};
this.getDefaultPageFilename = function(page_type, page_folder, title, page_template_id, page_template_path){
title = title || '';
if(page_type=='home') return '/' + _this.getDefaultPage();
if(page_template_id=='<Standalone>'){
//Get path from page_template_path
if(!page_template_path) return '';
if(page_template_path.indexOf('//')<0) return '';
var rslt_path = '';
try{
var parsed_page_template_path = XExt.getURLObj(page_template_path);
rslt_path = parsed_page_template_path.pathname || '';
}
catch(ex){
return '';
}
var rslt_file = XExt.basename(rslt_path);
if(!rslt_path) rslt_path = '/';
if(rslt_path && rslt_path[rslt_path.length-1]=='/') return rslt_path + _this.getDefaultPage();
else if(rslt_file && (rslt_file.indexOf('.')>=0)) return rslt_path;
else return rslt_path + '/' + _this.getDefaultPage();
}
if(!title.trim()) return '';
return page_folder + XExt.prettyURL(title.trim()) + '/' + _this.getDefaultPage();
};
this.addSitemapPage = function(sitemap_item_parent_id, page_type){
if(!_this.commitInfo()) return;
sitemap_item_parent_id = parseInt(sitemap_item_parent_id);
var sitemap_item_parent = _this.getSitemapItem(sitemap_item_parent_id);
if(!sitemap_item_parent) sitemap_item_parent = null;
//Get Parent Folder Path
var page_folder = '';
var cur_parent = sitemap_item_parent;
while(!page_folder && cur_parent){
if((cur_parent.sitemap_item_link_type=='PAGE') && cur_parent.sitemap_item_link_page){
page_folder = XExt.dirname(cur_parent.sitemap_item_link_page);
}
else if((cur_parent.sitemap_item_link_type=='URL') && cur_parent.sitemap_item_link_dest){
page_folder = XExt.dirname(cur_parent.sitemap_item_link_dest);
}
cur_parent = _this.getSitemapItem(cur_parent.sitemap_item_parent_id);
}
if(!page_folder) page_folder = '/';
if(page_folder[page_folder.length-1] != '/') page_folder += '/';
var xform = xmodel.controller.form;
var sel = '.'+xmodel.class+'_AddPage';
//Render Dialog for Page
XExt.CustomPrompt(sel, jsh.$root(sel)[0].outerHTML, function () { //onInit
var jprompt = jsh.$dialogBlock(sel);
XExt.RenderLOV(xform.Data, jsh.$dialogBlock(sel + ' .page_template_id'), xform.LOVs.page_template_id);
//Clear Values / Set Defaults
jprompt.find('.page_path').val('');
jprompt.find('.page_title').val('');
jprompt.find('.page_template_id').val(jsh.XPage.getBreadcrumbs().site_default_page_template_id);
jprompt.find('.page_template_path').val('');
jprompt.find('.page_path_default').prop('checked', true);
jprompt.find('.sitemap_item_text_default').prop('checked', true);
jprompt.find('.site_default_page_filename').text(jsh.XPage.getBreadcrumbs().site_default_page_filename);
var jfilename = jprompt.find('.page_path');
jfilename.prop('readonly', true);
jfilename.addClass('uneditable');
var jsitemaptext = jprompt.find('.sitemap_item_text');
jsitemaptext.prop('readonly', true);
jsitemaptext.addClass('uneditable');
var jTemplateId = jprompt.find('.page_template_id');
var jtitle = jprompt.find('.page_title');
var jTemplatePath = jprompt.find('.page_template_path');
function refreshDefaultValues(){
if(jprompt.find('.page_path_default').prop('checked')) jfilename.val(_this.getDefaultPageFilename(page_type, page_folder, jtitle.val(), jTemplateId.val(), jTemplatePath.val()));
if(jprompt.find('.sitemap_item_text_default').prop('checked')) jsitemaptext.val(jtitle.val());
}
var toggleTemplatePath = function(){
jprompt.find('.page_template_path_container,.page_template_path_tips').toggle(jTemplateId.val()=='<Standalone>');
jsh.XWindowResize();
};
jTemplateId.off('.template_path').on('change.template_path', function(e){ toggleTemplatePath(); refreshDefaultValues(); });
toggleTemplatePath();
jprompt.find('.page_title,.page_template_path').off('input keyup').on('input keyup', function(){ refreshDefaultValues(); });
jfilename.val(_this.getDefaultPageFilename(page_type, page_folder, jtitle.val(), jTemplateId.val(), jTemplatePath.val()));
jprompt.find('.page_path_default').off('click').on('click', function(){
if($(this).is(':checked')){
jfilename.prop('readonly', true);
jfilename.val(_this.getDefaultPageFilename(page_type, page_folder, jtitle.val(), jTemplateId.val(), jTemplatePath.val()));
jfilename.addClass('uneditable');
}
else{
jfilename.prop('readonly', false);
jfilename.removeClass('uneditable');
}
});
jprompt.find('.sitemap_item_text_default').off('click').on('click', function(){
if($(this).is(':checked')){
jsitemaptext.prop('readonly', true);
jsitemaptext.val(jtitle.val());
jsitemaptext.addClass('uneditable');
}
else{
jsitemaptext.prop('readonly', false);
jsitemaptext.removeClass('uneditable');
}
});
}, function (success) { //onAccept
var jprompt = jsh.$dialogBlock(sel);
//Validate File Selected
var page_path = jprompt.find('.page_path').val();
var page_title = jprompt.find('.page_title').val();
var page_template_id = jprompt.find('.page_template_id').val();
var page_template_path = jprompt.find('.page_template_path').val();
var sitemap_item_text = jprompt.find('.sitemap_item_text').val();
if (!page_template_id) return XExt.Alert('Please select a template.');
if (page_template_id=='<Standalone>'){
if (!page_template_path) return XExt.Alert('Please enter a page template URL.');
if (page_template_path.indexOf('//') < 0) return XExt.Alert('Page template URL should include the domain and protocol, ex: https://example.com/page');
}
else page_template_path = null;
if (!page_path) return XExt.Alert('Please enter a page path');
if (page_path[page_path.length-1]=='/') return XExt.Alert('Please enter a page filename');
if (XExt.cleanFilePath(page_path) != page_path) return XExt.Alert('Page path contains invalid characters');
if (page_path.indexOf('.') < 0) page_path += '.html';
var params = {
page_path: page_path,
page_title: page_title,
page_template_id: page_template_id,
page_template_path: page_template_path,
};
var execModel = xmodel.module_namespace+'Page_Tree_Listing';
XForm.Put(execModel, { }, params, function(rslt){ //On success
success();
//Add item to list
if(!rslt || !rslt[execModel] || !rslt[execModel].page_key) return XExt.Alert('Error creating page');
var page_key = rslt[execModel].page_key;
_this.addSitemapItem(sitemap_item_parent_id, {
sitemap_item_text: sitemap_item_text,
sitemap_item_link_type: 'PAGE',
sitemap_item_link_dest: page_key.toString(),
sitemap_item_link_page: params.page_path
});
}, function(err){ //On error
if(page_type=='home'){
var defaultHomePath = _this.getDefaultPageFilename(page_type);
if((page_path == defaultHomePath) && err && (err.Message == 'Application Error - Page file name already exists')){
XExt.Alert('Application Error - Home page aready added to this site: '+defaultHomePath);
}
}
});
});
};
this.addSitemapItem = function(sitemap_item_parent_id, new_sitemap_item){
if(!_this.commitInfo()) return;
sitemap_item_parent_id = parseInt(sitemap_item_parent_id);
var sitemap_item_parent = _this.getSitemapItem(sitemap_item_parent_id);
if(!sitemap_item_parent) sitemap_item_parent = null;
var max_sitemap_item_id = 0;
_.each(_this.sitemap_items, function(sitemap_item){ if(sitemap_item.sitemap_item_id >= max_sitemap_item_id) max_sitemap_item_id = sitemap_item.sitemap_item_id; });
var new_sitemap_item_id = max_sitemap_item_id+1;
new_sitemap_item = _.extend({ }, _this.sitemap_item_base, new_sitemap_item);
new_sitemap_item.sitemap_item_id = new_sitemap_item_id;
if(sitemap_item_parent){
new_sitemap_item.sitemap_item_parent_id = sitemap_item_parent.sitemap_item_id;
new_sitemap_item.sitemap_item_path = sitemap_item_parent.sitemap_item_path+new_sitemap_item_id.toString()+'/';
}
else {
new_sitemap_item.sitemap_item_path = '/'+new_sitemap_item_id.toString()+'/';
}
_this.sitemap_items.push(new_sitemap_item);
_this.setDirty(true);
_this.parseSitemap();
_this.renderSitemap();
_this.selectSitemapItem(new_sitemap_item_id);
window.setTimeout(function(){
jsh.$root('.sitemap_item_text.xelem'+_this.getModelInfo().class).focus();
//Scroll sitemap to item
var jtree = jsh.$root('.sitemap_item_id.xelem'+xmodel.class);
var jselected = jtree.find('.tree_item.selected').first();
if(jselected.length) XExt.scrollObjIntoView(jtree, jselected);
},1);
};
this.getEditorURL = function(page_key, cb){
if(page_key) _this.getPageInfo(page_key, function(page){
_this.openPageEditor(page, {
getURL: true,
async: false,
onComplete: function(err, url){
return cb(url);
}
});
}, { async: false });
};
this.getPageInfo = function(page_key, cb, options){
options = _.extend({ quiet: false, async: true }, options);
page_key = parseInt(page_key);
if(!page_key) return XExt.Alert('Page key is required');
//Get page settings from server
var execModel = xmodel.module_namespace+'Page_Info';
var pageQuery = { page_key: page_key, branch_id: null };
if(_this.sitemap_id){
pageQuery.branch_id = jsh._GET.branch_id;
}
XForm.Post(execModel, {}, pageQuery, function(rslt){
if(!rslt || !rslt[execModel] || !rslt[execModel].length){
if(options.quiet) return cb(null);
return XExt.Alert('Error loading page');
}
var page = rslt[execModel][0];
return cb(page);
}, undefined, { async: options.async });
};
this.openPageEditor = function(page, options){
options = _.extend({ readonly: false, getURL: false, onComplete: undefined, async: true }, options);
var page_key = page.page_key;
var page_id = page.page_id;
var page_template_id = page.page_template_id;
var page_template_path = page.page_template_path;
var page_filename = page.page_filename||'';
if(!page_template_id) return XExt.Alert('Invalid page template');
var editorParams = { source: 'sitemap', rawEditorDialog: '.'+xmodel.class+'_RawTextEditor', page_template_path: page_template_path };
if(options.readonly) editorParams.page_id = page_id;
if(options.getURL) editorParams.getURL = true;
if(options.onComplete) editorParams.onComplete = options.onComplete;
editorParams.async = options.async;
if(_this.sitemap_id && jsh._GET.branch_id){
editorParams.page_id = page_id;
editorParams.branch_id = jsh._GET.branch_id;
}
jsh.System.OpenPageEditor(page_key, page_filename, page_template_id, editorParams);
};
this.editPageContent = function(page_key){
if(!_this.commitInfo()) return;
page_key = parseInt(page_key);
if(!page_key) return XExt.Alert('Page key is required');
//Get page settings from server
_this.getPageInfo(page_key, function(page){
_this.openPageEditor(page);
});
};
this.editPageSettings = function(page_key, focus_target){
if(!_this.commitInfo()) return;
page_key = parseInt(page_key);
if(!page_key) return XExt.Alert('Page key is required');
var xform = xmodel.controller.form;
var sel = '.'+xmodel.class+'_PageSettings';
_this.getPageInfo(page_key, function(page){
//Render Dialog for Page
XExt.CustomPrompt(sel, jsh.$root(sel)[0].outerHTML, function () { //onInit
var jprompt = jsh.$dialogBlock(sel);
XExt.RenderLOV(xform.Data, jsh.$dialogBlock(sel + ' .page_template_id'), xform.LOVs.page_template_id);
//Clear Values / Set Defaults
jprompt.find('.page_path').val(page.page_path);
jprompt.find('.page_title').val(page.page_title);
jprompt.find('.page_template_id').val(page.page_template_id);
jprompt.find('.page_template_path').val(page.page_template_path);
jprompt.find('.site_default_page_filename').text(jsh.XPage.getBreadcrumbs().site_default_page_filename);
jprompt.find('input,select').removeClass('default_focus');
if(focus_target) jprompt.find('.'+focus_target).addClass('default_focus');
var jTemplateId = jprompt.find('.page_template_id');
var toggleTemplatePath = function(){ jprompt.find('.page_template_path_container,.page_template_path_tips').toggle(jTemplateId.val()=='<Standalone>'); jsh.XWindowResize(); };
jTemplateId.off('.template_path').on('change.template_path', function(e){ toggleTemplatePath(); });
toggleTemplatePath();
}, function (success) { //onAccept
var jprompt = jsh.$dialogBlock(sel);
//Validate File Selected
var page_path = jprompt.find('.page_path').val();
var page_title = jprompt.find('.page_title').val();
var page_template_id = jprompt.find('.page_template_id').val();
var page_template_path = jprompt.find('.page_template_path').val();
if (!page_template_id) return XExt.Alert('Please select a template.');
if (page_template_id=='<Standalone>'){
if (!page_template_path) return XExt.Alert('Please enter a page template URL.');
if (page_template_path.indexOf('//') < 0) return XExt.Alert('Page template URL should include the domain and protocol, ex: https://example.com/page');
}
else page_template_path = null;
if (!page_path) return XExt.Alert('Please enter a page path');
if (page_path[page_path.length-1]=='/') return XExt.Alert('Please enter a page filename');
if (XExt.cleanFilePath(page_path) != page_path) return XExt.Alert('Page path contains invalid characters');
if (page_path.indexOf('.') < 0) page_path += '.html';
var params = {
page_path: page_path,
page_title: page_title,
page_template_id: page_template_id,
page_template_path: page_template_path,
};
var execModel = xmodel.module_namespace+'Page_Tree_Listing';
XForm.Post(execModel, { page_key: page_key }, params, function(rslt){
success();
if(!rslt || !rslt[execModel] || !rslt._success) return XExt.Alert('Error updating page');
//Update Info, if applicable
var xmodelInfo = _this.getModelInfo();
var cur_sitemap_item_link_type = xmodelInfo.get('sitemap_item_link_type');
var cur_sitemap_item_link_dest = xmodelInfo.get('sitemap_item_link_dest');
if((cur_sitemap_item_link_type == 'PAGE') && ((cur_sitemap_item_link_dest||'').toString() == page_key.toString())){
xmodelInfo.set('sitemap_item_link_page', page_path);
jsh.App[xmodelInfo.id].updatePageInfo(true);
}
//Update URLs of all nodes that reference this page
for(var i=0;i<_this.sitemap_items.length;i++){
var sitemap_item = _this.sitemap_items[i];
var sitemap_item_link_type = sitemap_item.sitemap_item_link_type;
var sitemap_item_link_dest = (sitemap_item.sitemap_item_link_dest||'').toString();
if((sitemap_item_link_type=='PAGE') && (sitemap_item_link_dest == page_key.toString())){
sitemap_item.sitemap_item_link_page = page_path;
}
}
_this.parseSitemap();
_this.renderSitemap();
});
});
});
};
this.viewPageRevisions = function(page_key){
if(!_this.commitInfo()) return;
page_key = parseInt(page_key);
if(!page_key) return XExt.Alert('Page key is required');
_this.getPageInfo(page_key, function(page){
_this.revision_page_key = page_key;
_this.revision_page_id = page.page_id;
jsh.XExt.popupShow(xmodel.namespace + 'Page_Revision_Listing','revision_page','Revisions',undefined,jsh.$root('.xform'+xmodel.class+' .revision_page_xlookup')[0],{
OnControlUpdate:function(obj, rslt){
if(rslt && rslt.result){
var page_id = rslt.result;
XForm.Post(xmodel.namespace+'Page_Revision_Update',{},{ page_key: page_key, page_id: page_id }, function(){
//Refresh, if applicable
var xmodelInfo = _this.getModelInfo();
var cur_sitemap_item_link_type = xmodelInfo.get('sitemap_item_link_type');
var cur_sitemap_item_link_dest = xmodelInfo.get('sitemap_item_link_dest');
if((cur_sitemap_item_link_type == 'PAGE') && ((cur_sitemap_item_link_dest||'').toString() == page_key.toString())){
jsh.App[xmodelInfo.id].updatePageInfo(true);
}
});
}
}
});
});
};
this.previewPage = function(page_file){
_this.openPageEditor(page_file, { readonly: true });
};
this.duplicatePage = function(sitemap_item_parent_id, source_page_key){
if(!_this.commitInfo()) return;
source_page_key = parseInt(source_page_key);
if(!source_page_key) return XExt.Alert('Page key is required');
_this.getPageInfo(source_page_key, function(source_page){
sitemap_item_parent_id = parseInt(sitemap_item_parent_id);
var sitemap_item_parent = _this.getSitemapItem(sitemap_item_parent_id);
if(!sitemap_item_parent) sitemap_item_parent = null;
//Get Parent Folder Path
var page_folder = '';
var cur_parent = sitemap_item_parent;
while(!page_folder && cur_parent){
if((cur_parent.sitemap_item_link_type=='PAGE') && cur_parent.sitemap_item_link_page){
page_folder = XExt.dirname(cur_parent.sitemap_item_link_page);
}
else if((cur_parent.sitemap_item_link_type=='URL') && cur_parent.sitemap_item_link_dest){
page_folder = XExt.dirname(cur_parent.sitemap_item_link_dest);
}
cur_parent = _this.getSitemapItem(cur_parent.sitemap_item_parent_id);
}
if(!page_folder) page_folder = '/';
if(page_folder[page_folder.length-1] != '/') page_folder += '/';
var sel = '.'+xmodel.class+'_DuplicatePage';
//Render Dialog for Page
XExt.CustomPrompt(sel, jsh.$root(sel)[0].outerHTML, function () { //onInit
var jprompt = jsh.$dialogBlock(sel);
//Clear Values / Set Defaults
jprompt.find('.source_page_path').val(source_page.page_path);
jprompt.find('.page_path').val('');
jprompt.find('.page_title').val(source_page.page_title);
jprompt.find('.page_path_default').prop('checked', true);
jprompt.find('.sitemap_item_text_default').prop('checked', true);
var jfilename = jprompt.find('.page_path');
jfilename.prop('readonly', true);
jfilename.addClass('uneditable');
var jsitemaptext = jprompt.find('.sitemap_item_text');
jsitemaptext.prop('readonly', true);
jsitemaptext.addClass('uneditable');
var jtitle = jprompt.find('.page_title');
jtitle.off('input keyup').on('input keyup', function(){
if(jprompt.find('.page_path_default').prop('checked')) jfilename.val(_this.getDefaultPageFilename('', page_folder, jtitle.val()));
if(jprompt.find('.sitemap_item_text_default').prop('checked')) jsitemaptext.val(jtitle.val());
});
jsitemaptext.val(source_page.page_title);
jfilename.val(_this.getDefaultPageFilename('', page_folder, jtitle.val()));
jprompt.find('.page_path_default').off('click').on('click', function(){
if($(this).is(':checked')){
jfilename.prop('readonly', true);
jfilename.val(_this.getDefaultPageFilename('', page_folder, jtitle.val()));
jfilename.addClass('uneditable');
}
else{
jfilename.prop('readonly', false);
jfilename.removeClass('uneditable');
}
});
jprompt.find('.sitemap_item_text_default').off('click').on('click', function(){
if($(this).is(':checked')){
jsitemaptext.prop('readonly', true);
jsitemaptext.val(jtitle.val());
jsitemaptext.addClass('uneditable');
}
else{
jsitemaptext.prop('readonly', false);
jsitemaptext.removeClass('uneditable');
}
});
}, function (success) { //onAccept
var jprompt = jsh.$dialogBlock(sel);
//Validate File Selected
var page_path = jprompt.find('.page_path').val();
var page_title = jprompt.find('.page_title').val();
var sitemap_item_text = jprompt.find('.sitemap_item_text').val();
if (!page_path) return XExt.Alert('Please enter a page path');
if (page_path[page_path.length-1]=='/') return XExt.Alert('Please enter a page filename');
if (XExt.cleanFilePath(page_path) != page_path) return XExt.Alert('Page path contains invalid characters');
if (page_path.indexOf('.') < 0) page_path += '.html';
var params = {
page_key: source_page_key,
page_path: page_path,
page_title: page_title
};
var execModel = xmodel.module_namespace+'Sitemap_Tree_Page_Duplicate';
XForm.Post(execModel, {}, params, function(rslt){
success();
//Add item to list
if(!rslt || !rslt[execModel] || !rslt[execModel].length || !rslt[execModel][0] || !rslt[execModel][0].page_key) return XExt.Alert('Error creating page');
var page_key = rslt[execModel][0].page_key;
_this.addSitemapItem(sitemap_item_parent_id, {
sitemap_item_text: sitemap_item_text,
sitemap_item_link_type: 'PAGE',
sitemap_item_link_dest: page_key.toString(),
sitemap_item_link_page: params.page_path
});
});
});
});
};
this.save = function(options){
options = _.extend({ softSave: false }, options);
if(options.softSave){
//Previewing a revision
if(_this.sitemap_id) return;
//Invalid key
if(!_this.sitemap_key) return;
//No changes
if(!_this.has_changes) return;
}
else {
if(_this.sitemap_id){ XExt.Alert('Cannot save when previewing a revision'); return; }
if(!_this.sitemap_key){ XExt.Alert('Missing sitemap key'); return; }
if(!_this.commitInfo()) return;
}
var save_sitemap_items = [];
for(var i=0;i<_this.sitemap_items.length;i++){
var sitemap_item = _this.sitemap_items[i];
var save_sitemap_item = _.pick(sitemap_item, [
'sitemap_item_id',
'sitemap_item_parent_id',
'sitemap_item_path',
'sitemap_item_text',
'sitemap_item_type',
'sitemap_item_tag',
'sitemap_item_style',
'sitemap_item_class',
'sitemap_item_exclude_from_breadcrumbs',
'sitemap_item_exclude_from_parent_menu',
'sitemap_item_hide_menu_parents',
'sitemap_item_hide_menu_siblings',
'sitemap_item_hide_menu_children',
'sitemap_item_link_type',
'sitemap_item_link_dest',
'sitemap_item_link_target',
]);
save_sitemap_items.push(save_sitemap_item);
}
if(!save_sitemap_items.length) save_sitemap_items = '';
var url = jsh._BASEURL+'_funcs/sitemap/'+_this.sitemap_key;
XForm.Post(url, {}, { sitemap_items: JSON.stringify(save_sitemap_items) }, function (rslt) { //On Success
if ('_success' in rslt) {
_this.setDirty(false);
}
else{
XExt.Alert('Error saving sitemap');
}
}, function (err) {
});
};
})();