Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 1 | "use strict"; |
| 2 | |
| 3 | /* |
| 4 | Used for the newcustomimage_modal actions |
| 5 | |
| 6 | The .data('recipe') value on the outer element determines which |
| 7 | recipe ID is used as the basis for the new custom image recipe created via |
| 8 | this modal. |
| 9 | |
| 10 | Use newCustomImageModalSetRecipes() to set the recipes available as a base |
| 11 | for the new custom image. This will manage the addition of radio buttons |
| 12 | to select the base image (or remove the radio buttons, if there is only a |
| 13 | single base image available). |
| 14 | */ |
| 15 | |
| 16 | function newCustomImageModalInit(){ |
| 17 | |
| 18 | var newCustomImgBtn = $("#create-new-custom-image-btn"); |
| 19 | var imgCustomModal = $("#new-custom-image-modal"); |
| 20 | var invalidNameHelp = $("#invalid-name-help"); |
| 21 | var invalidRecipeHelp = $("#invalid-recipe-help"); |
| 22 | var nameInput = imgCustomModal.find('input'); |
| 23 | |
| 24 | var invalidNameMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-)."; |
| 25 | var duplicateNameMsg = "A recipe with this name already exists. Image names must be unique."; |
| 26 | var duplicateImageInProjectMsg = "An image with this name already exists in this project." |
| 27 | var invalidBaseRecipeIdMsg = "Please select an image to customise."; |
| 28 | |
| 29 | // capture clicks on radio buttons inside the modal; when one is selected, |
| 30 | // set the recipe on the modal |
| 31 | imgCustomModal.on("click", "[name='select-image']", function (e) { |
| 32 | clearRecipeError(); |
| 33 | |
| 34 | var recipeId = $(e.target).attr('data-recipe'); |
| 35 | imgCustomModal.data('recipe', recipeId); |
| 36 | }); |
| 37 | |
| 38 | newCustomImgBtn.click(function(e){ |
| 39 | e.preventDefault(); |
| 40 | |
| 41 | var baseRecipeId = imgCustomModal.data('recipe'); |
| 42 | |
| 43 | if (!baseRecipeId) { |
| 44 | showRecipeError(invalidBaseRecipeIdMsg); |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | if (nameInput.val().length > 0) { |
| 49 | libtoaster.createCustomRecipe(nameInput.val(), baseRecipeId, |
| 50 | function(ret) { |
| 51 | if (ret.error !== "ok") { |
| 52 | console.warn(ret.error); |
| 53 | if (ret.error === "invalid-name") { |
| 54 | showNameError(invalidNameMsg); |
| 55 | return; |
| 56 | } else if (ret.error === "recipe-already-exists") { |
| 57 | showNameError(duplicateNameMsg); |
| 58 | return; |
| 59 | } else if (ret.error === "image-already-exists") { |
| 60 | showNameError(duplicateImageInProjectMsg); |
| 61 | return; |
| 62 | } |
| 63 | } else { |
| 64 | imgCustomModal.modal('hide'); |
| 65 | window.location.replace(ret.url + '?notify=new'); |
| 66 | } |
| 67 | }); |
| 68 | } |
| 69 | }); |
| 70 | |
| 71 | function showNameError(text){ |
| 72 | invalidNameHelp.text(text); |
| 73 | invalidNameHelp.show(); |
| 74 | nameInput.parent().addClass('error'); |
| 75 | } |
| 76 | |
| 77 | function showRecipeError(text){ |
| 78 | invalidRecipeHelp.text(text); |
| 79 | invalidRecipeHelp.show(); |
| 80 | } |
| 81 | |
| 82 | function clearRecipeError(){ |
| 83 | invalidRecipeHelp.hide(); |
| 84 | } |
| 85 | |
| 86 | nameInput.on('keyup', function(){ |
| 87 | if (nameInput.val().length === 0){ |
| 88 | newCustomImgBtn.prop("disabled", true); |
| 89 | return |
| 90 | } |
| 91 | |
| 92 | if (nameInput.val().search(/[^a-z|0-9|-]/) != -1){ |
| 93 | showNameError(invalidNameMsg); |
| 94 | newCustomImgBtn.prop("disabled", true); |
| 95 | nameInput.parent().addClass('error'); |
| 96 | } else { |
| 97 | invalidNameHelp.hide(); |
| 98 | newCustomImgBtn.prop("disabled", false); |
| 99 | nameInput.parent().removeClass('error'); |
| 100 | } |
| 101 | }); |
| 102 | } |
| 103 | |
| 104 | // Set the image recipes which can used as the basis for the custom |
| 105 | // image recipe the user is creating |
| 106 | // |
| 107 | // baseRecipes: a list of one or more recipes which can be |
| 108 | // used as the base for the new custom image recipe in the format: |
| 109 | // [{'id': <recipe ID>, 'name': <recipe name>'}, ...] |
| 110 | // |
| 111 | // if recipes is a single recipe, just show the text box to set the |
| 112 | // name for the new custom image; if recipes contains multiple recipe objects, |
| 113 | // show a set of radio buttons so the user can decide which to use as the |
| 114 | // basis for the new custom image |
| 115 | function newCustomImageModalSetRecipes(baseRecipes) { |
| 116 | var imgCustomModal = $("#new-custom-image-modal"); |
| 117 | var imageSelector = $('#new-custom-image-modal [data-role="image-selector"]'); |
| 118 | var imageSelectRadiosContainer = $('#new-custom-image-modal [data-role="image-selector-radios"]'); |
| 119 | |
| 120 | // remove any existing radio buttons + labels |
| 121 | imageSelector.remove('[data-role="image-radio"]'); |
| 122 | |
| 123 | if (baseRecipes.length === 1) { |
| 124 | // hide the radio button container |
| 125 | imageSelector.hide(); |
| 126 | |
| 127 | // set the single recipe ID on the modal as it's the only one |
| 128 | // we can build from |
| 129 | imgCustomModal.data('recipe', baseRecipes[0].id); |
| 130 | } |
| 131 | else { |
| 132 | // add radio buttons; note that the handlers for the radio buttons |
| 133 | // are set in newCustomImageModalInit via event delegation |
| 134 | for (var i = 0; i < baseRecipes.length; i++) { |
| 135 | var recipe = baseRecipes[i]; |
| 136 | imageSelectRadiosContainer.append( |
| 137 | '<label class="radio" data-role="image-radio">' + |
| 138 | recipe.name + |
| 139 | '<input type="radio" class="form-control" name="select-image" ' + |
| 140 | 'data-recipe="' + recipe.id + '">' + |
| 141 | '</label>' |
| 142 | ); |
| 143 | } |
| 144 | |
| 145 | // show the radio button container |
| 146 | imageSelector.show(); |
| 147 | } |
| 148 | } |