/* Contains all the Javascript logic of the canvas and its main features: save, export and share */ $(document).ready(function() { /* ================================================ Miscellaneous ================================================= */ // Declare the currently loaded tags belonging to the user var tags; // This piece of code is for making the column-count and column-gap CSS to work in Firefox /* document.getElementById("7-5-col-layout").style.MozColumnCount = "7"; document.getElementById("2-col-layout").style.MozColumnCount = "2"; */ // Prevent pressing ENTER on Project Title from submitting the form $('.proj_title').keydown(function(event){ if(event.keyCode == 13) { event.preventDefault(); return false; } }); /* ================================================ Rearrange fields numerically if 1 column is displayed ================================================= */ // Declarations var groupOneLayout = $("#7-5-col-layout"); var groupTwoLayout = $("#4-col-layout"); var field01 = $("#panel_01"); var field03 = $("#panel_03"); var field04 = $("#panel_04"); var field09 = $("#panel_09"); var field05 = $("#panel_05"); var field06 = $("#panel_06"); var field02 = $("#panel_02"); var field07 = $("#panel_07"); var field08 = $("#panel_08"); var isRearranged = false; // Rearrange the fields to suit mobile function rearrangeFields() { field01.detach(); field03.detach(); field04.detach(); field09.detach(); field05.detach(); field06.detach(); field02.detach(); field07.detach(); field08.detach(); groupOneLayout.append(field01); groupOneLayout.append(field02); groupOneLayout.append(field03); groupOneLayout.append(field04); groupOneLayout.append(field05); groupOneLayout.append(field06); groupOneLayout.append(field07); groupOneLayout.append(field08); groupOneLayout.append(field09); } // Rearrange the fields according to their original order function rearrangeFieldsOriginal() { field01.detach(); field02.detach(); field03.detach(); field04.detach(); field05.detach(); field06.detach(); field07.detach(); field08.detach(); field09.detach(); groupOneLayout.append(field01); groupOneLayout.append(field03); groupOneLayout.append(field04); groupOneLayout.append(field09); groupOneLayout.append(field05); groupOneLayout.append(field06); groupOneLayout.append(field02); groupTwoLayout.append(field07); groupTwoLayout.append(field08); } // If the web page is opened on a mobile if ($(window).width() <= 499) { rearrangeFields(); } // When resizing the window $(window).on("resize", function() { if (isRearranged === false && $(window).width() <= 499) { rearrangeFields(); isRearranged = true; } else if(isRearranged === true && $(window).width() >= 500) { rearrangeFieldsOriginal(); isRearranged = false; } }); /* ================================================ "Jump to" functions ================================================= */ var hasScrolledDown = false; function showFixedJumpedTo() { // Add classes $("div.jump-to-click-area").addClass("jump-to-click-area-toggle"); $("div.jump-to").addClass("jump-to-toggle"); $("div.jump-to-list").addClass("jump-to-list-toggle"); $("img.jump-to-img").addClass("jump-to-img-toggle"); // If the user clicks on a link and scrolls up the page, hide list $("div.jump-to-list").hide(); } function showInitialJumpedTo() { // Toggle classes $("div.jump-to-click-area").removeClass("jump-to-click-area-toggle"); $("div.jump-to").removeClass("jump-to-toggle"); $("div.jump-to-list").removeClass("jump-to-list-toggle"); $("img.jump-to-img").removeClass("jump-to-img-toggle"); // If the user clicks on a link and scrolls up the page, toggle list $("div.jump-to-list").show(); hasScrolledDown = false; } // When the user scrolls down, change "position" to "fixed" $(window).scroll(function() { // If the web page is opened on a mobile if($(window).width() <= 499) { // Declarations var scrollPosition = $(window).scrollTop(); var jumpToPosition = $("div.jump-to").offset().top; // If the user has scrolled down to "Jump To..." if(hasScrolledDown === false && scrollPosition >= jumpToPosition) { showFixedJumpedTo(); // Update scroll position $(window).scrollTop($("div.saved-tags").offset().top - 300); hasScrolledDown = true; } // If the user has scrolled up to the top else if(hasScrolledDown === true && scrollPosition === 0) { showInitialJumpedTo(); } } // If the web page is not open on a mobile else { showInitialJumpedTo(); } }); // If the user clicks on "Jump to", show menu $("div.jump-to-click-area").on("click", function() { // Toggle the menu $("div.jump-to div div").slideToggle(300); // Rotate arrow // $("div.jump-to span.jump-to-arrow").toggleClass("rotate-arrow-180"); // $("div.jump-to span.jump-to-arrow").toggleClass("rotate-arrow-0"); $("img.jump-to-img").toggleClass("jump-to-arrow-90"); $("img.jump-to-img").toggleClass("jump-to-arrow-0"); return false; }); // If the user clicks on a menu item $("div.jump-to ul a").on("click", function() { // Declarations var chosenLiIndex = $(this).parent().index(); var chosenFieldPosition; var scrollPositionNew; // Detect the scroll position of the chosen field // If the user has chosen the list item 0 if(chosenLiIndex === 0) { chosenFieldPosition = $("div.saved-tags").offset().top; } // If the user has chosen the list item 1-9 else if(chosenLiIndex >= 1 && chosenLiIndex <= 9) { chosenFieldPosition = $("div.field_0" + chosenLiIndex).offset().top; } // If the user has chosen the list item 10 or higher else { chosenFieldPosition = $("div.field_" + chosenLiIndex).offset().top; } // If the user hasn't scrolled down if(hasScrolledDown === false) { console.log(chosenLiIndex); // Set the new scroll position scrollPositionNew = chosenFieldPosition - $("div.jump-to").height() - 89; // Add classes showFixedJumpedTo(); // Update scroll position hasScrolledDown = true; } // If the user has scrolled down to "Jump To..." else { // Set the new scroll position scrollPositionNew = chosenFieldPosition - 57; // Toggle the menu $("div.jump-to-list").slideToggle(300); // Rotate arrow // $("div.jump-to span.jump-to-arrow").toggleClass("rotate-arrow-90"); // $("div.jump-to span.jump-to-arrow").toggleClass("rotate-arrow-0"); $("img.jump-to-img").toggleClass("jump-to-arrow-90"); $("img.jump-to-img").toggleClass("jump-to-arrow-0"); } // Apply the new scroll position $(window).scrollTop(scrollPositionNew); return false; }); /* ================================================ Show tooltip for every category ================================================= */ $("a[data-toggle='tooltip']").tooltip({container: "body"}); $("a[data-toggle='tooltip']").on("click", function() { return false; }); /* ================================================ Remove all tags from all fields ================================================= */ // Remove all tags from all fields function removeTags() { // AJAX $.ajax({ type: "POST", url: "php/get-tags.php", dataType: "JSON", data: { "username": username }, timeout: 5000, success: function(returnData) { // Declarations var loopCounter = 0; tags = returnData; // For every added item $("li.added_item div").each(function() { var thisDiv = $(this); // Delete the declaration (because it's ugly!) // For every tag in the database that belongs to the active user for(t in tags) { // If the current tag exists in the textarea if(thisDiv.html().indexOf("") != -1) { // Delete the tag var text = thisDiv.html(); text = thisDiv.text().replace("" + tags[loopCounter] + "", tags[loopCounter]); thisDiv.html(text); } loopCounter++; } }); if(tags.length === 0) { $("div.saved-tags p").html("You haven't added any tags yet."); } }, error: function(xhr) { console.log(xhr.statusText); } }); /* // The code below is much better than the code above, because no database connection is being called, but the "You haven't added any tags yet" text is not being reset // Declarations var loopCounter = 0; // For every added item $("li.added_item div").each(function() { var thisDiv = $(this); // Delete the declaration (because it's ugly) // For every tag that belongs to the active user for(t in tags) { // If the current tag exists in the textarea if(thisDiv.html().indexOf("") != -1) { // Delete the tag var text = thisDiv.html(); text = thisDiv.text().replace("" + tags[loopCounter] + "", tags[loopCounter]); thisDiv.html(text); } loopCounter++; } }); console.log(tags); console.log(tags.length); if(tags.length === 0) { $("div.saved-tags p").html("You haven't added any tags yet."); } */ } /* ================================================ Get the user's tags from the database and apply them on the canvas ================================================= */ // Apply tags (Incoming parameter is an array with every tag from the database belonging to the active user) function applyTags() { var loopCounter = 0; // For every added item // $("li.added_item textarea").each(function() { $("li.added_item div").each(function() { // Here the selector is retrieving the objects it is supposed to... // For every tag in the database that belongs to the active user for(t in tags) { // console.log("tags.length: " + tags.length); // console.log("tag: " + tags[loopCounter]); // console.log($(this)); // console.log("Now working with " + tags[loopCounter]); // console.log($(this).html()); // console.log("The tag " + tags[loopCounter] + " has index '" + tags[loopCounter].indexOf(" ") + "' for ' '"); var text = $(this).html(); // If the current tag exists in the textarea if(text.indexOf(tags[loopCounter]) != -1) { // console.log($(this).html()); // ... But here the selector only seems to retrieve the first instance // console.log("Inside if!"); // Apply the tag text = text.replace(tags[loopCounter], "" + tags[loopCounter] + ""); $(this).html(text); } loopCounter++; } }); // Populate "Saved Tags" loopCounter = 0; var savedTags = $("div.saved-tags p"); savedTags.html(""); for(t in tags) { if(savedTags.html() === "You haven't added any tags yet.") { savedTags.html(""); } savedTags.append("" + tags[loopCounter] + "").append(" "); loopCounter++; } } // Get the tags from the database function getTags() { // Declarations var username = $("input[name='username']").val(); // AJAX $.ajax({ type: "POST", url: "php/get-tags.php", dataType: "JSON", data: { "username": username }, timeout: 5000, success: function(returnData) { if(returnData.length > 0) { // Assign returnData to the tags variable tags = returnData; // Sort the tags returnData.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()) }); // Apply the tags on the canvas applyTags(); showTagWindowOnTagClick(); } }, error: function(xhr) { console.log(xhr.statusText); } }); } /* ================================================ Load tags if the user is logged in ================================================= */ if($("input[name='name']").val() != "") { getTags(); } /* ================================================ Tag window functions ================================================= */ // Declarations // var textarea = $("div#tag-window textarea#tag-description"); var textareaHasBeenChanged = false; var tag; var tagIsNew = false; var username = $("input[name='username']").val(); // Check if the tag is new function checkIfTagIsNew() { // Declarations var tagToAJAX = tag; // AJAX $.ajax({ type: "POST", url: "php/check-if-tag-exists.php", dataType: "text", data: { "tag": tagToAJAX, "username": username }, timeout: 5000, success: function(returnData) { // If the current tag does not exist in the database if(returnData === "") { // Hide "Delete tag" button $("div#tag-window button#delete-tag").css("display", "none"); // Hide "Similar tags" $("div#tag-window h2.similar-tags").css("display", "none"); // The tag is new tagIsNew = true; } // If the current tag exists in the database else { // Show "Delete tag" button $("div#tag-window button#delete-tag").css("display", "inline"); // Show "Similar tags" $("div#tag-window h2.similar-tags").css("display", "block"); } }, error: function(xhr) { console.log(xhr.statusText); } }); } // Updating the remaining characters information function updateRemainingCharacters() { // Declarations var length = $("div#tag-window textarea#tag-description").val().length; // Retrieving from "Please enter a description..." var maxLength = 200; /* var length; if(description != "") { length = description; } else { length = $("div#tag-window textarea#tag-description").val().length; } */ // Update length length = maxLength - length; // Show the remaining characters $("div#tag-window span.chars").text(length); } // Get the description for the selected tag function getDescriptionForSelectedTag() { // Declarations var tagToAJAX = tag; // AJAX $.ajax({ type: "POST", url: "php/get-description-for-selected-tag.php", dataType: "text", data: { "tag": tagToAJAX, "username": username }, timeout: 5000, success: function(returnData) { if(returnData != "") { // Update description field with the description for the selected tag $("div#tag-window textarea#tag-description").val(returnData); // Update remaining characters updateRemainingCharacters(); } textareaHasBeenChanged = true; }, error: function(xhr) { console.log(xhr.statusText); } }); } // Get similar tags by other users function getSimilarTags() { // Declarations var tagToAJAX = tag; // AJAX $.ajax({ type: "POST", url: "php/get-similar-tags.php", dataType: "JSON", data: { "tag": tagToAJAX, "username": username }, timeout: 5000, success: function(returnData) { // Reset similar tags if similar tags are to be showed again $("p.similar-tags-tag").remove(); $("p.similar-tags-description").remove(); $("p.similar-tags-username").remove(); // Declarations var htmlToAppend = ""; // If similar tags exist if(returnData.length > 0) { // Declarations var index = 0; // While there still are tags to append while(index < returnData.length) { htmlToAppend += "
" + " " + " "; index++; } // Append tags $("div#tag-window h2.similar-tags").after(htmlToAppend); $("p.similar-tags-description-none").css("display", "none"); // Apply the tags on the canvas // applyTags(); // showTagWindowOnTagClick(); } else { // If the tag isn't a new tag if(tagIsNew === false) { // Show the message saying that there are no similar tags to show $("p.similar-tags-description-none").css("display", "block"); } } }, error: function(xhr) { console.log(xhr.statusText); } }); } // Close the tag window function closeTagWindow() { $("div#shadow").css("display", "none"); $("div#tag-window").css("display", "none"); } // Show the tag window function showTagWindow() { // Show the tag window $("div#shadow").css("display", "block"); $("div#tag-window").css("display", "block"); // Move the window to the centre of the screen /* The code below should be working, but the height of the second selector seems completely wrong! var middle = (document.body.clientHeight / 2) - ($("div#tag-window").height() / 2); $("div#tag-window").css("top", middle); */ // Check if the tag is new checkIfTagIsNew(); // Get the description for the selected tag getDescriptionForSelectedTag(); // Get tags by other users from the database getSimilarTags(); // Update remaining characters in case description is loaded updateRemainingCharacters(); // If a description hasn't been entered if($("div#tag-window textarea#tag-description") !== "Please enter a description..." && textareaHasBeenChanged !== true) { // Reset the remaining characters information $("div#tag-window span.chars").text("200"); } } // If the user presses a key in the description textarea $("div#tag-window textarea#tag-description").on("keyup", function() { // Update remaining characters updateRemainingCharacters(); }); // If the user clicks on the "Save tag" button $("div#tag-window #save-tag").on("click", function() { // Declarations var description = $("div#tag-window textarea#tag-description").val(); var tagToAJAX = tag; // If a description has been entered if(description != "" && description != "Please enter a description...") { // AJAX $.ajax({ timeout: 5000, dataType: "text", type: "post", data: { "tag": tagToAJAX, "description": description, "username": username }, url: "php/save-tag.php", success: function() { textareaHasBeenChanged = true; // Get the user's tags from the database and apply them on the canvas getTags(); }, error: function(xhr) { console.log(xhr.statusText); } }); // Close the tag window closeTagWindow(); } tagIsNew = false; }); // If the user clicks on the "Close" button $("div#tag-window button.close").on("click", function() { // Close the tag window closeTagWindow(); }); // If the user clicks on the "Delete tag" button $("div#tag-window #delete-tag").on("click", function() { // Declarations var tagToAJAX = tag; // AJAX $.ajax({ timeout: 5000, dataType: "text", type: "post", data: { "tag": tagToAJAX, "username": username }, url: "php/delete-tag.php", success: function() { // Remove all tags from all fields removeTags(); // Get the user's tags from the database and apply them on the canvas getTags(); }, error: function(xhr) { console.log(xhr.statusText); } }); // Close the tag window closeTagWindow(); }); // If the user focuses in the textarea $("div#tag-window textarea#tag-description").on("focusin", function() { // Declarations var description = $("div#tag-window textarea#tag-description").val(); // If a description hasn't been entered // if(textareaHasBeenChanged === false) { if(description === "Please enter a description...") { // Empty the description textarea $("div#tag-window textarea#tag-description").val(""); } }); // If the user focuses out the textarea $("div#tag-window textarea#tag-description").on("focusout", function() { // Declarations var description = $("div#tag-window textarea#tag-description").val(); // If a description hasn't been entered // if(textareaHasBeenChanged === false) { if(description === "") { // Reset the description textarea $("div#tag-window textarea#tag-description").val("Please enter a description..."); } }); /* ================================================ If the user types a new character in the added idea field, add tag if a term could be found ================================================= */ // 8an33j24 function applyTagOnTypeMatch() { $("li.added_item div").on("focusin", function() { // If the user presses a key in the description textarea $("li.added_item div").on("keyup", function() { if(event.which !== 9 && // Tab event.which !== 16 && // Shift event.which !== 37 && // Left event.which !== 38 && // Up event.which !== 39 && // Right event.which !== 40) { // Down // Declarations var bugCounter = 0; var loopCounter = 0; var tagLinkToSearch; var tagLinkHits; var tagTextToSearch; var tagTextHits; var text = $(this).html(); // Fix the bug that triggers the event twice if(!bugCounter > 0) { /* console.log("tagTextHits: " + tagTextHits); console.log("tagLinkHits: " + tagLinkHits); */ // For every tag that belongs to the active user for(t in tags) { if($(this).html().indexOf(tags[loopCounter]) != -1) { // Search for the tag inside the added idea as a link tagLinkToSearch = text.match(tags[loopCounter] + ""); // match() can only count to one instance (67hi9nt3) // Search for the tag inside the added idea as plain text tagTextToSearch = text.match(tags[loopCounter]); // match() can only count to one instance (67hi9nt3) // If the tag exists inside the added idea as a link if(tagLinkToSearch !== null) { // tagLinkHits = 1 tagLinkHits = tagLinkToSearch.length; } else { // tagLinkHits = 0 tagLinkHits = 0; } // If the tag exists inside the added idea as plain text if(tagTextToSearch !== null) { // tagTextHits = 1 tagTextHits = tagTextToSearch.length; } else { // tagTextHits = 0 tagTextHits = 0; } // If there are more instances of the tag as plain text than the tag as links, and there is a maximum of 1 instances of the tag as plain text // Change "tagTextHits <= 1" to "tagLinkHits === 0" if(tagTextHits > tagLinkHits && tagLinkHits === 0) { // Apply the tag text = text.replace(tags[loopCounter], "" + tags[loopCounter] + ""); $(this).html(text); } } loopCounter++; } } bugCounter++; } }); }); }; /* ---------------------------------------------- Limiting the number of characters the user is able to type ----------------------------------------------- */ var maxLength = 100; $('.card').on('keyup', '.new_item', function() { var length = $(this).val().length; length = maxLength - length; // show the characters remaining only on this field $(this).closest('.user-input').find('.chars').text(length); }); function limitLengthOnInput() { // Limit text on key press $("li.added_item div").on("keypress", function(event) { // Declarations var numberOfTags = $(this).children().filter("a").length; var textLength = $(this).html().length; // Subtract 43 from textLength per tag (the tag HTML is 43 characters) $(this).each(function() { textLength -= 43 * numberOfTags; }); if(textLength === 100) { // Windows menu/Right cmd event.preventDefault(); } }); // 28jek79t // Limit text on paste /* $("li.added_item div").on("paste", function(event) { var pastedText; $("li.added_item div").bind("paste", function(e) { pastedText = e.originalEvent.clipboardData.getData("Text"); console.log(pastedText); if($(this).html().length + pastedText >= 100) { event.preventDefault(); } }); // var text = $(this).html() // var length = text.length; // var newText = text.substring(0, maxLength); // if(length >= maxLength) { // $(this).html(newText); // Move the text cursor to the very end } }); */ } /* ================================================ If the user closes a dialog ================================================= */ $("div.dialog button").on("click", function() { $("div#shadow").css("display", "none"); $("div.dialog").css("display", "none"); }); /* ================================================ The user clicks on the "Tag selected term" link ================================================= */ // Declaration var selection = ""; // var newRange = ""; // Initiate tag tag = ""; // Update the tag variable document.onselectionchange = function() { // if($("textarea").is(":focus")) { if($("li.added_item div").is(":focus")) { // This is nicer: $("li.added_item div").on("focusin", function() { selection = window.getSelection().toString(); tag = selection.trim(); } } // If the user clicks on the "Tag selected term" link $("p.tag-selected-term a").on("click", function() { // If the tag isn't empty if(tag != "") { // Show the tag window showTagWindow(); } else { // Show a dialog $("div#shadow").css("display", "block"); $("div#dialog-select-term").css("display", "block"); } // Prevent the current view to jump to the top of the screen return false; }); // If the user moves the focus from the added idea, reset variables // $("li.added_item textarea").on("focusout", function() { $("li.added_item div").on("focusout", function() { selection = ""; tag = ""; }); /* ================================================ If the user clicks on a tag, show the tag window ================================================= */ // If the user clicks on a tag function showTagWindowOnTagClick() { $("a.tag").on("click", function() { // Event not triggered... // Declarations tag = $(this).text(); // If the user is logged in if($("input[name='username']").val() != "") { // Show the tag window showTagWindow(); } else { // Show a dialog $("div#shadow").css("display", "block"); $("div#dialog-log-in").css("display", "block"); } }); } /* // Mouse-enabled devices $("tag").mouseenter(function() { timer = setTimeout(function() { showTagWindow(); // showTagWindow needs a parameter! }, 400); }).mouseleave(function() { clearTimeout(timer); }); // Touch devices try { document.createEvent("TouchEvent"); $("a.tag").on("click", showTagWindow()); // showTagWindow needs a parameter! return true; } catch(e) { return false; } */ /* ================================================ Serialize Form to JSON ================================================= */ $.fn.serializeObject = function() { var o = {}; var a = this.serializeArray(); $.each(a, function() { if (o[this.name]) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return o; }; /* ================================================ Getting the current date ================================================= */ var fullDate = new Date(); var twoDigitMonth = fullDate.getMonth() + ""; if (twoDigitMonth.length == 1) twoDigitMonth = "0" + twoDigitMonth; var twoDigitDate = fullDate.getDate() + ""; if (twoDigitDate.length == 1) twoDigitDate = "0" + twoDigitDate; var currentDate = fullDate.getFullYear() + "-" + twoDigitMonth + "-" + twoDigitDate; // set the currebt date in the date input field $('.proj_date').val(currentDate); /* ================================================ USER LOGS OUT (dropdown menu) ================================================= */ $('.user-profile').on('click', '#logout', function() { var url = 'php/logout.php'; $.post(url, function(data, status) { if (data == 200) { $('.user-profile').hide(); window.location.href="https://www.ethicscanvas.org"; } }); }); /* ================================================ When the page loads, Import the chosen canvas if the user has picked one from the dashbord, otherwise load an empty canvas ================================================= */ // if a canvas is chosen by the user to be loaded if (current_canvas_id !== '') { var url = 'json/' + current_canvas_id + '.json'; // var url= 'json/test_canvas.json'; // get the saved ISON object in the sendJSON.text file $.getJSON(url, function(returnedObj) { // Display the json data in the html var itemListHTML = ''; // iterate through the object $.each(returnedObj, function(key, value) { // project name and tem field if (key === 'field_00[]') { $('.form-header').find('input.proj_title').val(value[ 0]); $('.form-header').find('input.proj_date').val(value[1]); } else if (key !== 'new_item') { if ($.type(value) === "array") { $.each(value, function(i, itm) { /** FIX DUPLICATIONs in the canvas when importing /* Importing will override the canvas content clear the canvas by giving en emty content to the ul list (remove previous list items) */ $('.canvas-form').find('.card').filter('.' + key.substr(0, 8)).find('ul.item_list').html(''); /* Create a list item with each value item and give it text area with the name attribute as the "key" (right field name) */ itemListHTML += // 'Your canvas is saved in your dashbord
Oh! We could not save your canvas. Please try again or contact us at hello@ethicscanvas.org
Your canvas has been shared by email
Your canvas could not be shared by email