diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index d947126..d06a457 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,3 +14,9 @@ //= require jquery_ujs //= require turbolinks //= require modernizr-lite/modernizr +//= require button-group +//= require form-animation +//= require summary-edit +//= require test-builder +//= require textarea-limit +//= require live-coder diff --git a/app/assets/javascripts/button-group.js b/app/assets/javascripts/button-group.js new file mode 100644 index 0000000..727382b --- /dev/null +++ b/app/assets/javascripts/button-group.js @@ -0,0 +1,8 @@ +/** + * Button Group Functionality + */ + +$('.btn-group button').click(function() { + $(this).siblings().removeClass('selected'); + $(this).addClass('selected'); +}); diff --git a/app/assets/javascripts/form-animation.js b/app/assets/javascripts/form-animation.js new file mode 100644 index 0000000..8601b37 --- /dev/null +++ b/app/assets/javascripts/form-animation.js @@ -0,0 +1,17 @@ +// Text Input Label Animation + +var textInput = $('[type="color"], [type="date"], [type="datetime"], [type="datetime-local"], [type="email"], [type="month"], [type="number"], [type="password"], [type="search"], [type="tel"], [type="text"], [type="time"], [type="url"], [type="week"], input:not([type]), textarea'); + +textInput.prev('label').addClass('loaded'); +$(textInput).each(function() { + if( $(this).val() ) { + $(this).prev('label').addClass('animate'); + } +}); +$(textInput).on('focus', function() { + $(this).prev('label').addClass('animate'); +}).on('focusout', function() { + if( !$(this).val() ) { + $(this).prev('label').removeClass('animate'); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/live-coder.js.erb b/app/assets/javascripts/live-coder.js.erb new file mode 100644 index 0000000..54c90fa --- /dev/null +++ b/app/assets/javascripts/live-coder.js.erb @@ -0,0 +1,127 @@ +function updateResults(includeJavascript) { + // var includeJavascript = includeJavascript; + // + // if (!(typeof(includeJavascript) != 'undefined' && includeJavascript == true)){ + // includeJavascript = false; + // } + + var resultsContainer = document.querySelectorAll('[data-id="results"]')[0]; + var codeHtml = document.querySelectorAll('[data-id="code-html"]')[0].value.trim(); + var codeCss = document.querySelectorAll('[data-id="code-css"]')[0].value.trim(); + + // if(includeJavascript == true){ + var codeJs = document.querySelectorAll('[data-id="code-js"]')[0].value.trim(); + // } + + resultsContainer.innerHTML = ""; + var iDoc = document.createElement('html'); + var iHead = document.createElement('head'); + var iBody = document.createElement('body'); + + var codeFrame = document.createElement('iframe'); + codeFrame.setAttribute("width", "100%"); + codeFrame.setAttribute("height", "100%"); + resultsContainer.appendChild(codeFrame); + + var codeStyle = document.createElement("style"); + codeStyle.setAttribute("type", "text/css"); + var rulesNode = document.createTextNode(codeCss); + codeStyle.appendChild(rulesNode); + iHead.appendChild(codeStyle); + iDoc.appendChild(iHead); + + iBody.innerHTML = codeHtml; + iDoc.appendChild(iBody); + + // if(includeJavascript == true){ + var codeScript = document.createElement("script"); + codeScript.setAttribute("type", "text/javascript"); + var scriptNode = document.createTextNode(codeJs); + codeScript.appendChild(scriptNode); + iDoc.appendChild(codeScript); + // } + + codeFrame.contentWindow.document.open(); + codeFrame.contentWindow.document.appendChild(iDoc); + codeFrame.contentWindow.document.close(); +} + +function indentSelection(e){ + if(e.keyCode === 9){ + e.preventDefault(); + + var indent = " "; + var cursor = e.target.selectionStart; + var val = e.target.value; + var valStart = val.substring(0, e.target.selectionStart); + var valEnd = val.substring(e.target.selectionEnd, val.length); + var selected = val.substring(e.target.selectionStart, e.target.selectionEnd); + + var resetCursor = function(start, end){ + e.target.selectionStart = start; + e.target.selectionEnd = end; + }; + + var indented; + if(e.shiftKey){ //de-indent + if(selected.length > 0 && (/\n/.test(selected))){ //multi line + indented = selected.split(/\n/).map(function(line){ + if(line.length > 0 && line.substring(0, indent.length) === indent){ + line = line.substring(indent.length, line.length); + } + return line; + }).join("\n"); + e.target.value = valStart + indented + val.substring(e.target.selectionEnd, val.length); + resetCursor(cursor, cursor + indented.length); + } else { + if(valStart.substring(valStart.length - indent.length) === indent){ + e.target.value = valStart.substring(0, valStart.length - indent.length) + valEnd; + resetCursor(cursor, cursor - indent.length); + } else if(valEnd.substring(0, indent.length) === indent) { + e.target.value = valStart + valEnd.substring(indent.length, valEnd.length); + resetCursor(cursor, cursor); + } + } + } else { //indent + if(selected.length > 0 && (/\n/.test(selected))){ //multi line + indented = selected.split(/\n/).map(function(line){ + if(line.length > 0){ line = indent + line; } + return line; + }).join("\n"); + e.target.value = valStart + indented + val.substring(e.target.selectionEnd, val.length); + resetCursor(cursor, cursor + indented.length); + } else { + e.target.value = valStart + indent + selected + valEnd; + resetCursor(cursor + indent.length, cursor + indent.length); + } + } + } +} + +timer = 0; + +$(function(){ + // wait a half second before updating results + // restart the timer if they resume typing + $('html').on('keyup', '.code-input textarea', function(){ + if (timer) { clearTimeout(timer); } + timer = setTimeout(updateResults, 500); + }); + + $("html").on('keydown', "textarea[data-id^=code-]", function(e){ + indentSelection(e); + }); + + // If JavaScript is enabled, display the livecoder section dynamically + $("[data-id='live-coder-answer']").load("live-coder-chunk.php .layout", function(){ + // if it loads in, and hide "finish later" checkbox + $("[data-id='live-coder-finish-later']").addClass("hidden"); + $('.js-error').addClass('hidden'); + updateResults(); + }); + + $("[data-id=live-coder]").each(function(){ + updateResults(); + }); + +}); diff --git a/app/assets/javascripts/summary-edit.js b/app/assets/javascripts/summary-edit.js new file mode 100644 index 0000000..0102519 --- /dev/null +++ b/app/assets/javascripts/summary-edit.js @@ -0,0 +1,162 @@ +/** + * Summary Page Answer Editor + */ + +(function($){ + $.fn.setTextAreaHeight = function(input) { + return this.each(function(){ + var lineHeight = parseInt($(this).css('line-height')); + var rows = Math.ceil(input / lineHeight); + rows = rows == 0 ? 1 : rows; + + $(this).attr('rows', rows); + }) + } + + $('input[type="radio"]').on('change', function() { + var inputName = $(this).attr('name'); + //$('input[name="'+inputName+'"]').attr('checked', false); + var value = $(this).attr('value'); + $('input[name="'+inputName+'"][value="'+value+'"]').attr("checked",true); + $('input[name="'+inputName+'"]').each(function() { + if($(this).val() != value) { + $(this).attr('checked', false); + } + }); + }); + + // $('.run-js').hide().delay(); +}(jQuery)); + +var existingValue = []; + +var editClickHandler = function(e) { + e.preventDefault(); + var thisEd = $(e.delegateTarget); + var height = thisEd.find('p').height(); + thisEd.data('answer', thisEd.find('p').text()); + if(thisEd.find('input').attr('type') == 'radio') { + existingValue = thisEd.find('input:checked').val(); + } + else if(thisEd.find('input').attr('type') == 'checkbox') { + $(thisEd.find('input')).each(function() { + if($(this).prop('checked')==true) { + existingValue.push($(this).val()); + } + }); + } + + $('.button-edit, .submit-button').addClass('disabled-button'); + thisEd.addClass('editable'); + thisEd.find('.text-answer:not(.code-answer)').replaceWith(''); + thisEd.find('.answer-block, .code-answer').prop('disabled', false); + thisEd.find('textarea').setTextAreaHeight(height); + thisEd.find('textarea.answer-block').focus(); + thisEd.find('.button-edit').hide().delay(); + thisEd.find('.button-save, .button-cancel').show().delay(); + // thisEd.find('button.run-js').show().delay(); +}; + +var cancelClickHandler = function(e) { + e.preventDefault(); + var thisEd = $(e.delegateTarget); + if(thisEd.find('input').attr('type') == 'radio') { + $(thisEd.find('input')).each(function() { + if($(this).val()!=existingValue) { + $(this).attr('checked', false).prop('checked', false); + } + else { + $(this).prop('checked', true); + } + }); + } + else if(thisEd.find('input').attr('type') == 'checkbox') { + $(existingValue).each(function(index, value) { + thisEd.find('input[value="'+value+'"]').prop('checked', true); + }); + } + $('.success, .error').remove(); + $('.button-edit, .submit-button').removeClass('disabled-button'); + thisEd.removeClass('editable'); + thisEd.find('textarea:not(.code-answer)').replaceWith('

' + $.trim(thisEd.data('answer')) + '

'); + thisEd.find('.answer-block, .code-answer').prop('disabled', true); + thisEd.find('.button-edit').show(); + thisEd.find('.button-save, .button-cancel').hide(); + // thisEd.find('button.run-js').hide(); + existingValue = []; +}; + +var saveClickHandler = function(e) { + e.preventDefault(); + var thisEd = $(e.delegateTarget); + var data =[]; + var executeQuery; + var questionId = thisEd.find('.button-edit').attr('data-questionid'); + if(thisEd.find('input').attr('type')=='radio') { + $(thisEd.find('input')).each(function() { + if($(this).prop('checked')==true) { + data = $(this).val(); + } + }); + } else if(thisEd.find('input').attr('type')=='checkbox') { + $(thisEd.find('input')).each(function() { + if($(this).prop('checked')==true) { + data.push($(this).val()); + } + }); + } else if (thisEd.find('textarea.code-answer')) { + var htmlAnswer = $(thisEd.find('textarea.code-html')[0]).val(); + var cssAnswer = $(thisEd.find('textarea.code-css')[0]).val(); + var jsAnswer = $(thisEd.find('textarea.code-js')[0]).val(); + data = { + 'html': htmlAnswer, + 'css': cssAnswer, + 'js': jsAnswer + } + } else { + data = thisEd.find('textarea').val(); + } + if(data == '') { + $(thisEd).before('
Please select or enter a value.
'); + } else { + thisEd.find('textarea:not(.code-answer)').replaceWith('

' + $.trim(thisEd.find('textarea').val()) + '

'); + $.ajax({ + type: "POST", + url: "assets/update_from_summary.php", + data:{ id: questionId, answer: data}, + success: function(data){ + executeQuery = true; + //console.log(data); + }, + error: function(data){ + executeQuery = false; + } + }).done(function() { + if(executeQuery == true) { + $('.success, .error').remove(); + $(thisEd).before('
Your answer has been updated successfully!
'); + $(thisEd).find('.code-answer').attr('disabled', true); + } + if(executeQuery == false) { + $('.error, .success').remove(); + $(thisEd).before('
Oops! There was an error processing your request. Please try again.
'); + } + }); + + $('.button-edit, .submit-button').removeClass('disabled-button'); + thisEd.removeClass('editable'); + thisEd.find('.answer-block').prop('disabled', true); + thisEd.find('.button-edit').show(); + thisEd.find('.button-save, .button-cancel').hide(); +} +}; + +$('.answer-block').prop('disabled', true); + +// Question events + $('.answer-sec') + .find('.button-cancel, .button-save').hide().end() +// // delegating events + .on('click', '.button-edit', editClickHandler) + .on('click', '.button-cancel', cancelClickHandler) + .on('click', '.button-save', saveClickHandler); diff --git a/app/assets/javascripts/test-builder.js b/app/assets/javascripts/test-builder.js new file mode 100644 index 0000000..25fca79 --- /dev/null +++ b/app/assets/javascripts/test-builder.js @@ -0,0 +1,66 @@ +$(document).ready(function() { + //$(".answer_container").hide(); + //$(".test-builder-success").hide(); + //$(".question-edit-container").hide(); + + $(".skills-app-form").each(function () { + var thisQu = $(this), + questionOf = thisQu.find(".question-block").text(); + + + thisQu.find(".testbuilderquestion").val(questionOf); + + thisQu.find(".answer_type").change(function(){ + if ( $(this).val() == "1" ) { + thisQu.find(".answer_container").hide(); + thisQu.find(".answer_container.answer_text").show(); + } + if ( $(this).val() == "2" ) { + thisQu.find(".answer_container").hide(); + thisQu.find(".answer_container.answer_multiple").show(); + } + if ( $(this).val() == "3" ) { + thisQu.find(".answer_container").hide(); + thisQu.find(".answer_container.answer_multiple").show(); + } + }); + thisQu.find(".test-builder-edit").click(function(){ + thisQu.find(".question-display").slideUp().fadeOut(); + thisQu.find(".question-edit-container").slideDown().fadeIn(); + }); + thisQu.find(".btn-saveedit").click(function(){ + if(thisQu.valid()) { + thisQu.find(".question-display").slideDown().fadeIn(); + thisQu.find(".question-edit-container").slideUp().fadeOut(); + thisQu.find(".test-builder-success").slideDown().fadeIn(); + thisQu.find(".test-builder-success").delay(3000).slideUp().fadeOut(); + } + }); + thisQu.find(".btn-cancel-edit").click(function(){ + thisQu.find(".question-display").slideDown().fadeIn(); + thisQu.find(".question-edit-container").slideUp().fadeOut(); + }); + thisQu.find(".btn-cancel").click(function(){ + thisQu.find(".answer_container").hide(); + }); + thisQu.find(".skills-app-form").submit(function() { + return false; + }); + thisQu.find(".test-builder-save").click(function(){ + if(thisQu.valid()) { + thisQu.find(".answer_container").hide(); + thisQu.find(".test-builder-success").slideDown(); + thisQu.find(".test-builder-success").delay(3000).slideUp(); + } + else { + thisQu.find(".form-validation-script:invalid").css("border-color", "red"); + } + }); + thisQu.find( ".btn-save" ).click(function() { + if(thisQu.valid()) { + window.location.href = "test-builder-success.html"; + } + }); + }); + +}); \ No newline at end of file diff --git a/app/assets/javascripts/textarea-limit.js b/app/assets/javascripts/textarea-limit.js new file mode 100644 index 0000000..ca9ee07 --- /dev/null +++ b/app/assets/javascripts/textarea-limit.js @@ -0,0 +1,30 @@ +$(document).ready(function() { + setTextAreaLimit(); + +function setTextAreaLimit() { + $.fn.extend({ + limiter: function(limit, elem) { + $('textarea').on("keyup focus show", function() { + setCount(this, elem); + }); + + function setCount(src, elem) { + if(src != undefined) { + var chars = src.value.length; + if (chars > limit) { + src.value = src.value.substr(0, limit); + chars = limit; + } + elem.html(limit - chars); + } + } + setCount($(this)[0], elem); + } + }); + var elem = $(".chars span"); + $('textarea').limiter(1000, elem); + //$('input').limiter(1000, elem); + //$('.Question-1').addClass('active'); +} + +}); \ No newline at end of file