From c46b1485354b39b675b41b1f285070b68de21346 Mon Sep 17 00:00:00 2001 From: hjkhjk54 Date: Mon, 25 Jun 2012 17:34:25 +0000 Subject: [PATCH] Updates for page management, including updating link to menu ordering on page list, updating internal class server side logic to correctly instantiate objects when editing an internal class page (previously json object was passed but wasn't needed so removed from constructor), also updated client-side script to correctly populate internal class/class group section and other client-side interactions --- ...cessIndividualsForClassesDataGetterN3.java | 21 +- ...IndividualsForClassesDataGetterN3Test.java | 32 -- webapp/web/js/menupage/pageManagementUtils.js | 462 ++++++++++-------- .../processClassGroupDataGetterContent.js | 3 + .../web/js/menupage/processDataGetterUtils.js | 6 + .../processFixedHTMLDataGetterContent.js | 4 + ...sIndividualsForClassesDataGetterContent.js | 10 +- .../processSparqlDataGetterContent.js | 4 + .../body/pagemanagement/pageList.ftl | 2 +- .../freemarker/edit/forms/pageManagement.ftl | 18 +- 10 files changed, 296 insertions(+), 266 deletions(-) delete mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3Test.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3.java index 92aaf4e0c..98443c248 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3.java @@ -32,18 +32,12 @@ import net.sf.json.JSONSerializer; //Returns the appropriate n3 for selection of classes from within class group public class ProcessIndividualsForClassesDataGetterN3 extends ProcessClassGroupDataGetterN3 { private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter"; - protected JSONObject values = null; int classCount = 0; protected static String individualClassVarNameBase = "classesSelectedInClassGroup"; private Log log = LogFactory.getLog(ProcessIndividualsForClassesDataGetterN3.class); - public ProcessIndividualsForClassesDataGetterN3(JSONObject jsonObject){ - this.values = jsonObject; - if(values != null && values.containsKey(individualClassVarNameBase)) { - //Check how many individual classes are in json object - JSONArray ja = values.getJSONArray(individualClassVarNameBase); - classCount = ja.size(); - } + public ProcessIndividualsForClassesDataGetterN3(){ + } //Pass in variable that represents the counter @@ -71,14 +65,7 @@ public class ProcessIndividualsForClassesDataGetterN3 extends ProcessClassGroup String n3 = dataGetterVar + " <" + DisplayVocabulary.GETINDIVIDUALS_FOR_CLASS + "> "; //Consider a multi-valued field - in this case single field with multiple values n3 += getN3VarName(individualClassVarNameBase, counter); - /* - int i; - for(i = 0; i < classCount; i++) { - if(i != 0) { - n3+= ","; - } - n3 += getN3VarName(individualClassVarNameBase + counter, classCount); - }*/ + n3 += " ."; return n3; @@ -230,7 +217,7 @@ public class ProcessIndividualsForClassesDataGetterN3 extends ProcessClassGroup jObject.element("classGroup", classGroupURI); //this is a json array - jObject.element("classesSelectedInClassGroup", individualsForClasses); + jObject.element(individualClassVarNameBase, individualsForClasses); } catch(Exception ex) { log.error("Exception occurred in retrieving existing values with query " + querystr, ex); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3Test.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3Test.java deleted file mode 100644 index 72254f382..000000000 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessIndividualsForClassesDataGetterN3Test.java +++ /dev/null @@ -1,32 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils; - -import static org.junit.Assert.*; - -import java.util.List; - -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; - -import org.junit.Test; - -public class ProcessIndividualsForClassesDataGetterN3Test { - - @Test - public void testRetrieveN3Required() { - JSONObject jsonObject = new JSONObject(); - JSONArray ja = new JSONArray(); - ja.add("test1"); - ja.add("test2"); - jsonObject.element("classesSelectedInClassGroup", ja); - ProcessIndividualsForClassesDataGetterN3 pn = new ProcessIndividualsForClassesDataGetterN3(jsonObject); - List retrievedN3 = pn.retrieveN3Required(0); - String firstString = retrievedN3.get(0); - //check whether correct type returned - int index = firstString.indexOf(pn.getClassType()); - assert(firstString.indexOf(index) != -1); - } - - -} diff --git a/webapp/web/js/menupage/pageManagementUtils.js b/webapp/web/js/menupage/pageManagementUtils.js index e8c987e3a..3d17001a7 100644 --- a/webapp/web/js/menupage/pageManagementUtils.js +++ b/webapp/web/js/menupage/pageManagementUtils.js @@ -119,8 +119,10 @@ var pageManagementUtils = { this.headerBar = $("section#headerBar"); this.doneButton = $("input#doneWithContent"); this.isMenuCheckbox = $("input#menuCheckbox"); + this.menuLinkText = $("input#menuLinkText"); this.menuSection = $("section#menu"); - this.submitButton = $("input#submit"); + this.pageNameInput = $("input#pageName"); + this.pageSaveButton = $("input#pageSave"); this.leftSideDiv = $("div#leftSide"); this.rightSideDiv = $("div#rightSide"); //contentDivs container where content added/existing placed @@ -141,10 +143,14 @@ var pageManagementUtils = { // tlw72 this.moreContentButton.hide(); //left side components //These depend on whether or not this is an existing item or not - if(this.isAdd() && !this.isAddMenuItem()) { + if(this.isAdd()) { this.defaultTemplateRadio.attr('checked',true); - this.isMenuCheckbox.attr('checked',false); - this.menuSection.hide(); + //disable save button + this.disablePageSave(); + if(!this.isAddMenuItem()) { + this.isMenuCheckbox.attr('checked',false); + this.menuSection.hide(); + } } }, @@ -169,41 +175,10 @@ var pageManagementUtils = { } }); - this.submitButton.click( function() { - $("section#pageDetails").show(); - }); - //Collapses the current content and creates a new section of content //Resets the content to be cloned to default settings this.doneButton.click( function() { - var selectedType = pageManagementUtils.contentTypeSelect.val(); - var selectedTypeText = $("#typeSelect option:selected").text(); - - //Hide all sections - pageManagementUtils.classGroupSection.hide(); - pageManagementUtils.fixedHTMLSection.hide(); - pageManagementUtils.sparqlQuerySection.hide(); - //Reset main content type drop-down - pageManagementUtils.contentTypeSelectOptions.eq(0).attr('selected', 'selected'); - if ( pageManagementUtils.leftSideDiv.css("height") != undefined ) { - pageManagementUtils.leftSideDiv.css("height",""); - if ( pageManagementUtils.leftSideDiv.height() < pageManagementUtils.rightSideDiv.height() ) { - pageManagementUtils.leftSideDiv.css("height",pageManagementUtils.rightSideDiv.height() + "px"); - } - } - pageManagementUtils.headerBar.hide(); - pageManagementUtils.headerBar.text(""); - pageManagementUtils.cloneContentArea(selectedType, selectedTypeText); - //Reset class group section AFTER cloning not before - pageManagementUtils.resetClassGroupSection(); - //Clear all inputs values - pageManagementUtils.clearSourceTemplateValues(); - //If adding browse classgroup, need to remove the classgroup option from the dropdown - if(selectedType == "browseClassGroup") { - pageManagementUtils.handleAddBrowseClassGroupPageContent(); - } - pageManagementUtils.contentTypeSelect.focus(); - + pageManagementUtils.handleClickDone(); }); //replacing with menu management edit version which is extended with some of the logic below @@ -218,23 +193,71 @@ var pageManagementUtils = { //Submission: validate as well as create appropriate hidden json inputs $("form").submit(function (event) { - var validationError = pageManagementUtils.validateMenuItemForm(); - //Add any errors from page content sections - validationError += pageManagementUtils.validatePageContentSections(); - if (validationError == "") { - //Create the appropriate json objects - pageManagementUtils.createPageContentForSubmission(); - return true; - } else{ - - $('#error-alert').removeClass('hidden'); - $('#error-alert p').html(validationError); - $.scrollTo({ top:0, left:0}, 500) - return false; - } + pageManagementUtils.handleFormSubmission(event); }); }, + handleClickDone:function() { + var selectedType = pageManagementUtils.contentTypeSelect.val(); + var selectedTypeText = $("#typeSelect option:selected").text(); + + //Hide all sections + pageManagementUtils.classGroupSection.hide(); + pageManagementUtils.fixedHTMLSection.hide(); + pageManagementUtils.sparqlQuerySection.hide(); + //Reset main content type drop-down + pageManagementUtils.contentTypeSelectOptions.eq(0).attr('selected', 'selected'); + if ( pageManagementUtils.leftSideDiv.css("height") != undefined ) { + pageManagementUtils.leftSideDiv.css("height",""); + if ( pageManagementUtils.leftSideDiv.height() < pageManagementUtils.rightSideDiv.height() ) { + pageManagementUtils.leftSideDiv.css("height",pageManagementUtils.rightSideDiv.height() + "px"); + } + } + pageManagementUtils.headerBar.hide(); + pageManagementUtils.headerBar.text(""); + pageManagementUtils.cloneContentArea(selectedType, selectedTypeText); + //Reset class group section AFTER cloning not before + pageManagementUtils.resetClassGroupSection(); + //Clear all inputs values + pageManagementUtils.clearSourceTemplateValues(); + //If adding browse classgroup, need to remove the classgroup option from the dropdown + if(selectedType == "browseClassGroup") { + pageManagementUtils.handleAddBrowseClassGroupPageContent(); + } + //Enable save button now that some content has been selected + pageManagementUtils.enablePageSave(); + pageManagementUtils.contentTypeSelect.focus(); + + }, + //Form submission + handleFormSubmission:function(event) { + var validationError = pageManagementUtils.validateMenuItemForm(); + //Add any errors from page content sections + validationError += pageManagementUtils.validatePageContentSections(); + if (validationError == "") { + //Check if menu label needs to be page title + pageManagementUtils.checkMenuTitleSubmission(); + //Create the appropriate json objects + pageManagementUtils.createPageContentForSubmission(); + return true; + } else{ + + $('#error-alert').removeClass('hidden'); + $('#error-alert p').html(validationError); + event.preventDefault(); + return false; + } + }, + checkMenuTitleSubmission:function() { + var isMenu = pageManagementUtils.isMenuCheckbox.is(":checked"); + var linkText = pageManagementUtils.menuLinkText.val(); + if(isMenu && linkText == "") { + //substitute with page title instead + var pageName = pageManagementUtils.pageNameInput.val(); + pageManagementUtils.menuLinkText.val(pageName); + } + }, + //Select content type handleContentTypeSelect:function() { _this = pageManagementUtils; @@ -277,7 +300,17 @@ var pageManagementUtils = { //Collapse any divs for existing content if it exists pageManagementUtils.collapseAllExistingContent(); //adjust save button height - pageManagementUtils.adjustSaveButtonHeight(); + pageManagementUtils.adjustSaveButtonHeight(); + //Disable save button until the user has clicked done or cancel from the addition + pageManagementUtils.disablePageSave(); + }, + disablePageSave:function() { + pageManagementUtils.pageSaveButton.attr("disabled", "disabled"); + pageManagementUtils.pageSaveButton.addClass("disabledSubmit"); + }, + enablePageSave:function() { + pageManagementUtils.pageSaveButton.removeAttr("disabled"); + pageManagementUtils.pageSaveButton.removeClass("disabledSubmit"); }, collapseAllExistingContent:function() { var spanArrows = pageManagementUtils.savedContentDivs.find("span.pageContentExpand div.arrow"); @@ -309,6 +342,8 @@ var pageManagementUtils = { }, //Clone content area + //When adding a new content type, this function will copy the values from the new content form and generate + //the content for the new section containing the content cloneContentArea: function(contentType, contentTypeLabel) { var ctr = pageManagementUtils.counter; var counter = pageManagementUtils.counter; @@ -334,17 +369,7 @@ var pageManagementUtils = { //previously increased by 10, just increasing by 1 here pageManagementUtils.counter++; }, - //For edit, need to have text passed in - //Returns new content object itself - cloneContentAreaForEdit: function(contentType, contentTypeLabel, labelText) { - var counter = pageManagementUtils.counter; - //Clone the object, renaming ids and copying text area values as well - $newContentObj = pageManagementUtils.createCloneObject(contentType, counter); - pageManagementUtils.createClonedContentContainer($newContentObj, counter, contentTypeLabel, labelText); - //previously increased by 10, just increasing by 1 here - pageManagementUtils.counter++; - return $newContentObj; - }, + //For binding content type specific event handlers should they exist bindClonedContentEventHandlers:function($newContentObj) { var dataGetterProcessorObj = pageManagementUtils.getDataGetterProcessorObject($newContentObj); @@ -426,13 +451,113 @@ var pageManagementUtils = { event.preventDefault(); }); }, - resetClassGroupSection:function() { - //doing this in clear inputs instead which will be triggered - //every time content type is changed AS well as on more content button after - //original content is cloned and stored - //$('select#selectClassGroup option').eq(0).attr('selected', 'selected'); - pageManagementUtils.classesForClassGroup.addClass('hidden'); + //clones and returns cloned object for content type + createCloneObject:function(contentType, counter) { + var originalObjectPath = 'section#' + contentType; + var $newContentObj = $(originalObjectPath).clone(); + $newContentObj.removeClass("sparqlHtmlContent"); + $newContentObj.addClass("pageContent"); + $newContentObj.attr("contentNumber", counter); + //Save content type + $newContentObj.attr("contentType", contentType); + //Set id for object + $newContentObj.attr("id", contentType + counter); + $newContentObj.show(); + pageManagementUtils.renameIdsInClone($newContentObj, counter); + // pageManagementUtils.cloneTextAreaValues(originalObjectPath, $newContentObj); + return $newContentObj; }, + //This is specifically for cloning text area values + //May not need this if implementing the jquery fix + ///would need a similar function for select as well + cloneTextAreaValues:function(originalAncestorPath, $newAncestorObject) { + $(originalAncestorPath + " textarea").each(function(index, el) { + var originalTextAreaValue = $(this).val(); + var originalTextAreaName = $(this).attr("name"); + $newAncestorObject.find("textarea[name='" + originalTextAreaName + "']").val(originalTextAreaValue); + }); + }, + //given an object and a counter, rename all the ids + renameIdsInClone:function($newContentObj, counter) { + $newContentObj.find("[id]").each(function(index, el) { + var originalId = $(this).attr("id"); + var newId = originalId + counter; + $(this).attr("id", newId); + }); + }, + /**Existing Content**/ + //For edit, need to have text passed in + //Returns new content object itself + cloneContentAreaForEdit: function(contentType, contentTypeLabel, labelText) { + var counter = pageManagementUtils.counter; + //Clone the object, renaming ids and copying text area values as well + $newContentObj = pageManagementUtils.createCloneObject(contentType, counter); + //Attach done event + //Bind done event as the done button is within the cloned content + pageManagementUtils.bindClonedContentDoneEvent($newContentObj); + //create cloned content container + pageManagementUtils.createClonedContentContainer($newContentObj, counter, contentTypeLabel, labelText); + //previously increased by 10, just increasing by 1 here + pageManagementUtils.counter++; + return $newContentObj; + }, + //To actually generate the content for existing values + generateExistingContentSections:function() { + if(pageManagementUtils.menuAction == "Edit") { + var $existingContent = $("#existingPageContentUnits"); + //create json object from string version json2. + if($existingContent.length > 0) { + var jsonObjectString = $existingContent.val(); + //this returns an array + var JSONContentObjectArray = JSON.parse(jsonObjectString); + var len = JSONContentObjectArray.length; + var i; + for(i = 0; i < len; i++) { + //Get the type of data getter and create the appropriate section/populate + var JSONContentObject = JSONContentObjectArray[i]; + var dataGetterClass = JSONContentObject["dataGetterClass"]; + if(dataGetterClass != null) { + //Get the Label for the URI + var contentType = pageManagementUtils.dataGetterURIToLabel[dataGetterClass]; + var contentTypeForCloning = pageManagementUtils.processDataGetterUtils.getContentTypeForCloning(contentType); + //Get the processor class for this type + var dataGetterProcessorObject = pageManagementUtils.processDataGetterUtils.dataGetterProcessorMap[contentType]; + var contentTypeLabel = dataGetterProcessorObject.retrieveContentLabel(); + var additionalLabelText = dataGetterProcessorObject.retrieveAdditionalLabelText(JSONContentObject); + //Clone the appropriate section for the label + var $newContentObj = pageManagementUtils.cloneContentAreaForEdit(contentTypeForCloning, contentTypeLabel, additionalLabelText); + //Populate the section with the values + dataGetterProcessorObject.populatePageContentSection(JSONContentObject, $newContentObj); + //Also include a hidden input with data getter URI + pageManagementUtils.includeDataGetterURI(JSONContentObject, $newContentObj); + //If content type is browseClassGroup or other 'related types' that are derived from it + if(pageManagementUtils.processDataGetterUtils.isRelatedToBrowseClassGroup(contentType)) { + pageManagementUtils.handleAddBrowseClassGroupPageContent(); + } + } else { + //error condition + } + } + + } + + } + }, + //What's the label of the content type from the drop down + getContentTypeLabelFromSelect:function(contentType) { + var text= pageManagementUtils.contentTypeSelect.find("option[value='" + contentType + "']").text(); + if(text == null) { + text = ""; + } + return text; + }, + includeDataGetterURI:function(JSONContentObject, $newContentObj) { + var uri = JSONContentObject["URI"]; + if(uri != null) { + $("").appendTo($newContentObj); + } + }, + //Adjust save button height adjustSaveButtonHeight:function() { if ( $("div#leftSide").css("height") != undefined ) { @@ -442,8 +567,16 @@ var pageManagementUtils = { } } }, - /************************************/ + /***Class group selection***/ //Copied from menu management edit javascript + //Class group + resetClassGroupSection:function() { + //doing this in clear inputs instead which will be triggered + //every time content type is changed AS well as on more content button after + //original content is cloned and stored + //$('select#selectClassGroup option').eq(0).attr('selected', 'selected'); + pageManagementUtils.classesForClassGroup.addClass('hidden'); + }, chooseClassGroup: function() { var url = "dataservice?getVClassesForVClassGroup=1&classgroupUri="; var vclassUri = this.selectClassGroupDropdown.val(); @@ -523,49 +656,10 @@ var pageManagementUtils = { //Set content type within internal class message this.displayInternalMessage.filter(":first").html(classGroupName); }, - validateMenuItemForm: function() { - var validationError = ""; - - // Check menu name - if ($('input[type=text][name=pageName]').val() == "") { - validationError += "You must supply a name
"; - } - // Check pretty url - if ($('input[type=text][name=prettyUrl]').val() == "") { - validationError += "You must supply a pretty URL
"; - } - if ($('input[type=text][name=prettyUrl]').val().charAt(0) != "/") { - validationError += "The pretty URL must begin with a leading forward slash
"; - } - - // Check custom template - if ($('input:radio[name=selectedTemplate]:checked').val() == "custom") { - if ($('input[name=customTemplate]').val() == "") { - validationError += "You must supply a template
"; - } - } - - //the different types of error will depend on the specific type of data getter/page content - /* - - // if no class group selected, this is an error - if ($('#selectClassGroup').val() =='-1') { - validationError += "You must supply a content type
"; - } else { - //class group has been selected, make sure there is at least one class selected - var allSelected = $('input[name="allSelected"]:checked').length; - var noClassesSelected = $('input[name="classInClassGroup"]:checked').length; - if (allSelected == 0 && noClassesSelected == 0) { - //at least one class should be selected - validationError += "You must select the type of content to display
"; - } - } - */ - - //check select class group - - return validationError; - }, + + /**On submission**/ + //On submission, generates the content for the input that will return the serialized JSON objects representing + //each of the content types createPageContentForSubmission: function() { //Iterate through the page content and create the appropriate json object and save var pageContentSections = $("section[class='pageContent']"); @@ -607,88 +701,7 @@ var pageManagementUtils = { //Error handling here return null; }, - //clones and returns cloned object for content type - createCloneObject:function(contentType, counter) { - var originalObjectPath = 'section#' + contentType; - var $newContentObj = $(originalObjectPath).clone(); - $newContentObj.removeClass("sparqlHtmlContent"); - $newContentObj.addClass("pageContent"); - $newContentObj.attr("contentNumber", counter); - //Save content type - $newContentObj.attr("contentType", contentType); - //Set id for object - $newContentObj.attr("id", contentType + counter); - $newContentObj.show(); - pageManagementUtils.renameIdsInClone($newContentObj, counter); - // pageManagementUtils.cloneTextAreaValues(originalObjectPath, $newContentObj); - return $newContentObj; - }, - //This is specifically for cloning text area values - //May not need this if implementing the jquery fix - ///would need a similar function for select as well - cloneTextAreaValues:function(originalAncestorPath, $newAncestorObject) { - $(originalAncestorPath + " textarea").each(function(index, el) { - var originalTextAreaValue = $(this).val(); - var originalTextAreaName = $(this).attr("name"); - $newAncestorObject.find("textarea[name='" + originalTextAreaName + "']").val(originalTextAreaValue); - }); - }, - //given an object and a counter, rename all the ids - renameIdsInClone:function($newContentObj, counter) { - $newContentObj.find("[id]").each(function(index, el) { - var originalId = $(this).attr("id"); - var newId = originalId + counter; - $(this).attr("id", newId); - }); - }, - //To actually generate the content for existing values - generateExistingContentSections:function() { - if(pageManagementUtils.menuAction == "Edit") { - var $existingContent = $("#existingPageContentUnits"); - //create json object from string version json2. - if($existingContent.length > 0) { - var jsonObjectString = $existingContent.val(); - //this returns an array - var JSONContentObjectArray = JSON.parse(jsonObjectString); - var len = JSONContentObjectArray.length; - var i; - for(i = 0; i < len; i++) { - //Get the type of data getter and create the appropriate section/populate - var JSONContentObject = JSONContentObjectArray[i]; - var dataGetterClass = JSONContentObject["dataGetterClass"]; - if(dataGetterClass != null) { - //Get the Label for the URI - var contentType = pageManagementUtils.dataGetterURIToLabel[dataGetterClass]; - //Get the label for this content t - var contentTypeLabel = "test label"; - //Get the processor class for this type - var dataGetterProcessorObject = pageManagementUtils.processDataGetterUtils.dataGetterProcessorMap[contentType]; - var additionalLabelText = dataGetterProcessorObject.retrieveAdditionalLabelText(JSONContentObject); - //Clone the appropriate section for the label - var $newContentObj = pageManagementUtils.cloneContentAreaForEdit(contentType, contentTypeLabel, additionalLabelText); - //Populate the section with the values - dataGetterProcessorObject.populatePageContentSection(JSONContentObject, $newContentObj); - //Also include a hidden input with data getter URI - pageManagementUtils.includeDataGetterURI(JSONContentObject, $newContentObj); - //If content type is browseClassGroup or other 'related types' that are derived from it - if(pageManagementUtils.processDataGetterUtils.isRelatedToBrowseClassGroup(contentType)) { - pageManagementUtils.handleAddBrowseClassGroupPageContent(); - } - } else { - //error condition - } - } - - } - - } - }, - includeDataGetterURI:function(JSONContentObject, $newContentObj) { - var uri = JSONContentObject["URI"]; - if(uri != null) { - $("").appendTo($newContentObj); - } - }, + //Get the data getter processor getDataGetterProcessorObject:function(pageContentSection) { var dataGetterType = pageManagementUtils.processDataGetterUtils.selectDataGetterType(pageContentSection); @@ -719,26 +732,57 @@ var pageManagementUtils = { } return label; }, + /***Validation***/ + validateMenuItemForm: function() { + var validationError = ""; + + // Check menu name + if ($('input[type=text][name=pageName]').val() == "") { + validationError += "You must supply a name
"; + } + // Check pretty url + if ($('input[type=text][name=prettyUrl]').val() == "") { + validationError += "You must supply a pretty URL
"; + } + if ($('input[type=text][name=prettyUrl]').val().charAt(0) != "/") { + validationError += "The pretty URL must begin with a leading forward slash
"; + } + + // Check custom template + if ($('input:radio[name=selectedTemplate]:checked').val() == "custom") { + if ($('input[name=customTemplate]').val() == "") { + validationError += "You must supply a template
"; + } + } + + + return validationError; + }, //Validation across different content types validatePageContentSections:function() { //Get all page content sections var pageContentSections = $("section[class='pageContent']"); var validationErrorMsg = ""; - //For each, based on type, validate if a validation function exists - $.each(pageContentSections, function(i) { - if(pageManagementUtils.processDataGetterUtils != null) { - var dataGetterType = pageManagementUtils.processDataGetterUtils.selectDataGetterType($(this)); - if(pageManagementUtils.dataGetterProcessorMap != null) { - var dataGetterProcessor = pageManagementUtils.dataGetterProcessorMap[dataGetterType]; - //the content type specific processor will create the json object to be returned - if($.isFunction(dataGetterProcessor.validateFormSubmission)) { - //Get label of page content section - var label = pageManagementUtils.getPageContentSectionLabel($(this)); - validationErrorMsg += dataGetterProcessor.validateFormSubmission($(this), label); - } - } - } - }); + //If there ARE not contents selected, then error message should indicate user needs to add them + if(pageContentSections.length == 0) { + validationErrorMsg = "You must select content to be included on the page
"; + } else { + //For each, based on type, validate if a validation function exists + $.each(pageContentSections, function(i) { + if(pageManagementUtils.processDataGetterUtils != null) { + var dataGetterType = pageManagementUtils.processDataGetterUtils.selectDataGetterType($(this)); + if(pageManagementUtils.dataGetterProcessorMap != null) { + var dataGetterProcessor = pageManagementUtils.dataGetterProcessorMap[dataGetterType]; + //the content type specific processor will create the json object to be returned + if($.isFunction(dataGetterProcessor.validateFormSubmission)) { + //Get label of page content section + var label = pageManagementUtils.getPageContentSectionLabel($(this)); + validationErrorMsg += dataGetterProcessor.validateFormSubmission($(this), label); + } + } + } + }); + } return validationErrorMsg; } diff --git a/webapp/web/js/menupage/processClassGroupDataGetterContent.js b/webapp/web/js/menupage/processClassGroupDataGetterContent.js index dfc26314e..e413a8b70 100644 --- a/webapp/web/js/menupage/processClassGroupDataGetterContent.js +++ b/webapp/web/js/menupage/processClassGroupDataGetterContent.js @@ -33,6 +33,9 @@ var processClassGroupDataGetterContent = { } }, //For the label of the content section for editing, need to add additional value + retrieveContentLabel:function() { + return "Browse Class Group"; + }, retrieveAdditionalLabelText:function(existingContentObject) { var label = ""; var results = existingContentObject["results"]; diff --git a/webapp/web/js/menupage/processDataGetterUtils.js b/webapp/web/js/menupage/processDataGetterUtils.js index 094fee8da..f02067df5 100644 --- a/webapp/web/js/menupage/processDataGetterUtils.js +++ b/webapp/web/js/menupage/processDataGetterUtils.js @@ -28,5 +28,11 @@ var processDataGetterUtils = { }, isRelatedToBrowseClassGroup:function(contentType) { return (contentType == "browseClassGroup" || contentType == "individualsForClasses"); + }, + getContentTypeForCloning:function(contentType) { + if(contentType == "browseClassGroup" || contentType == "individualsForClasses") { + return "browseClassGroup"; + } + return contentType; } }; \ No newline at end of file diff --git a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js index 4cb3fbf41..0b7c3a827 100644 --- a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js +++ b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js @@ -24,6 +24,10 @@ var processFixedHTMLDataGetterContent = { pageContentSection.find("textarea[name='htmlValue']").val(htmlValue); }, //For the label of the content section for editing, need to add additional value + retrieveContentLabel:function() { + return "Fixed HTML"; + }, + //For the label of the content section for editing, need to add additional value retrieveAdditionalLabelText:function(existingContentObject) { var saveToVarValue = existingContentObject["saveToVar"]; return saveToVarValue; diff --git a/webapp/web/js/menupage/processIndividualsForClassesDataGetterContent.js b/webapp/web/js/menupage/processIndividualsForClassesDataGetterContent.js index 042e78dd6..873121910 100644 --- a/webapp/web/js/menupage/processIndividualsForClassesDataGetterContent.js +++ b/webapp/web/js/menupage/processIndividualsForClassesDataGetterContent.js @@ -20,11 +20,15 @@ var processIndividualsForClassesDataGetterContent = { var returnObject = {classGroup:classGroup, classesSelectedInClassGroup:classesSelected, dataGetterClass:this.dataGetterClass}; return returnObject; }, + //For the label of the content section for editing, need to add additional value + retrieveContentLabel:function() { + return processClassGroupDataGetterContent.retrieveContentLabel(); + }, //For an existing set of content where form is already set, fill in the values populatePageContentSection:function(existingContentObject, pageContentSection) { //select class group in dropdown and append the classes within that class group processClassGroupDataGetterContent.populatePageContentSection(existingContentObject, pageContentSection); - var classesSelected = existingContenetObject["classesSelectedInClassGroup"]; + var classesSelected = existingContentObject["classesSelectedInClassGroup"]; var numberSelected = classesSelected.length; var i; //Uncheck all since default is checked @@ -39,8 +43,8 @@ var processIndividualsForClassesDataGetterContent = { return processClassGroupDataGetterContent.retrieveAdditionalLabelText(existingContentObject); }, //Validation on form submit: Check to see that class group has been selected - validateFormSubmission: function(pageContentSection) { - return processClassGroupDataGetterContent.validateFormSubmission(pageContentSection); + validateFormSubmission: function(pageContentSection, pageContentSectionLabel) { + return processClassGroupDataGetterContent.validateFormSubmission(pageContentSection, pageContentSectionLabel); } } \ No newline at end of file diff --git a/webapp/web/js/menupage/processSparqlDataGetterContent.js b/webapp/web/js/menupage/processSparqlDataGetterContent.js index 823dc4b36..1935e8784 100644 --- a/webapp/web/js/menupage/processSparqlDataGetterContent.js +++ b/webapp/web/js/menupage/processSparqlDataGetterContent.js @@ -29,6 +29,10 @@ var processSparqlDataGetterContent = { pageContentSection.find("input[name='queryModel']").val(queryModelValue); }, //For the label of the content section for editing, need to add additional value + retrieveContentLabel:function() { + return "SPARQL Query Results"; + }, + //For the label of the content section for editing, need to add additional value retrieveAdditionalLabelText:function(existingContentObject) { var saveToVarValue = existingContentObject["saveToVar"]; return saveToVarValue; diff --git a/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl index f9be483a4..9c860dafb 100644 --- a/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl +++ b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl @@ -68,7 +68,7 @@
-

Use Menu Management to set the order of menu items.

+

Use Menu Ordering to set the order of menu items.

diff --git a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl index aceec4eee..deebe1d77 100644 --- a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl +++ b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl @@ -33,15 +33,25 @@ <#assign menuPosition = editMenuPosition/> +<#--If edit submission exists, then retrieve validation errors if they exist--> +<#if editSubmission?has_content && editSubmission.submissionExists = true && editSubmission.validationErrors?has_content> + <#assign submissionErrors = editSubmission.validationErrors/> + <#------------HTML Portion-------------> -