2 /*******************************************************************************
3 * Copyright (c) 2012-2014 University of Stuttgart.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * and the Apache License 2.0 which both accompany this distribution,
7 * and are available at http://www.eclipse.org/legal/epl-v10.html
8 * and http://www.apache.org/licenses/LICENSE-2.0
11 * Oliver Kopp - initial API and implementation and/or initial documentation
12 *******************************************************************************/
14 <%@tag description="Dialog to change a req or cap. Offers function showEditDiagFor${shortName}(id)" pageEncoding="UTF-8"%>
16 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
17 <%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %>
18 <%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%>
19 <%@taglib prefix="w" tagdir="/WEB-INF/tags"%>
20 <%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%>
22 <%@attribute name="headerLabel" required="true"%>
23 <%@attribute name="shortName" required="true" description="Used for diag id, function name suffix, Req|Cap"%>
24 <%@attribute name="requirementOrCapability" required="true" description="requirement|capability"%>
25 <%@attribute name="cssClassPrefix" required="true"%>
26 <%@attribute name="allTypes" required="true" type="java.util.Collection" description="Collection<QName> of all available types" %>
27 <%@attribute name="clazz" required="true" type="java.lang.Class" description="TRequirement.class or TCapability.class" %>
28 <%@attribute name="repositoryURL" required="true" %>
30 <div class="modal fade" id="AddOrUpdate${shortName}Diag">
31 <div class="modal-dialog">
32 <div class="modal-content" style="width:660px;">
33 <div class="modal-header">
34 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
35 <h4 class="modal-title"><span id="headerAddOrUpdate"></span> ${headerLabel}</h4>
37 <div class="modal-body">
38 <form id="add${shortName}Form" enctype="multipart/form-data">
40 <w:idInput inputFieldId="${shortName}Id"/>
42 <div class="form-group">
43 <label for="${shortName}NameChooser" class="control-label">Definition Name:</label>
44 <input id="${shortName}NameChooser" class="form-control" type="text" required="required" />
47 <div class="form-group">
48 <label for="${shortName}TypeDisplay" class="control-label">${shortName} Type:</label>
49 <input id="${shortName}TypeDisplay" class="form-control" type="text" required="required" disabled="disabled"/>
52 <div id="${shortName}PropertiesContainer">
57 <div class="modal-footer">
58 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
59 <button type="button" id="add${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(false);">Add</button>
60 <button type="button" id="delete${shortName}btn" class="btn btn-danger" onclick="deleteCurrent${shortName}();">Delete</button>
61 <button type="button" id="update${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(true);">Change</button>
70 * The following variables are declared twice due to double inclusion of this .tag flie
71 * Due to JavaScript magic, it works nevertheless
73 var selectedNodeTemplateForReqCapAddition;
75 //global variable set by editPropertiesXML and read by save${shortName}Edits
76 var nodeTemplateEditedReqOrCap;
79 function deleteCurrent${shortName}() {
80 nodeTemplateEditedReqOrCap.remove();
81 $("#AddOrUpdate${shortName}Diag").modal("hide");
84 function update${shortName}PropertiesContainerWithClone(propertiesContainerToClone) {
85 var clone = propertiesContainerToClone.clone();
86 $("#${shortName}PropertiesContainer").empty().append(clone);
87 clone.find(".KVPropertyValue").editable({mode: "inline"});
90 function update${shortName}PropertiesFromSelectedType() {
91 var data = $("#${shortName}NameChooser").select2("data");
96 // TODO: use qname2href and store QName in data-qname for later consumption -- possibly qname2href should always store the qname in data-qname
97 $("#${shortName}TypeDisplay").val(type);
99 // fill in properties (derived from type)
100 var propertiesContainer= $(".skelettonPropertyEditorFor${shortName} > span:contains('" + type + "')").parent().children("div");
101 update${shortName}PropertiesContainerWithClone(propertiesContainer);
104 $("#${shortName}NameChooser").on("change", function(e) {
105 update${shortName}PropertiesFromSelectedType();
109 * Called when a req/cap should be added or updated
110 * Update mode is triggered if reqOrCapIdtoUpdate is given
112 * @param nodeTemplateId the node template id to add a req/cap to. undefined in update mode
113 * @param reqOrCapIdtoUpdate
115 function showAddOrUpdateDiagFor${shortName}(nodeTemplateId, reqOrCapIdToUpdate) {
116 var update = (typeof reqOrCapIdToUpdate !== "undefined");
119 nodeTemplateEditedReqOrCap = $("#" + reqOrCapIdToUpdate);
120 // in update mode, nodeTemplateId is not provided, we have to search for the right shape
121 selectedNodeTemplateForReqCapAddition = nodeTemplateEditedReqOrCap.closest(".NodeTemplateShape");
123 selectedNodeTemplateForReqCapAddition = $("#" + nodeTemplateId);
126 require(["winery-support-common"], function(wsc) {
127 var typeQName = selectedNodeTemplateForReqCapAddition.children("div.headerContainer").children("span.typeQName").text();
128 var urlFragment = wsc.getURLFragmentOutOfFullQName(typeQName);
129 var url = "${repositoryURL}/nodetypes/" + urlFragment + "/${requirementOrCapability}definitions/";
133 }).fail(function(jqXHR, textStatus, errorThrown) {
134 vShowAJAXError("Could not fetch ${requirementOrCapability} definitions", jqXHR, errorThrown);
135 }).done(function(data) {
136 // now, we have all available requirement definitions
137 // we have to ask each of it for the type
138 // we use the type as key for the option and the name as displayed text
139 // select2 perfectly handles duplicate keys
141 var select2Data = [];
143 $.each(data, function(i,e) {
144 var rqDefURL = url + e + "/type";
149 }).fail(function(jqXHR, textStatus, errorThrown) {
150 vShowAJAXError("Could not fetch type for " + e, jqXHR, errorThrown);
151 }).done(function(data) {
156 select2Data.push(item);
160 $("#${shortName}NameChooser").select2({
161 placeholder: "Select name",
166 $("#add${shortName}btn").hide();
167 $("#update${shortName}btn").show();
168 $("#delete${shortName}btn").show();
169 $("#headerAddOrUpdate").text("Change");
171 // collect existing data in variables
172 var id = nodeTemplateEditedReqOrCap.children(".id").text();
173 var name = nodeTemplateEditedReqOrCap.children(".name").text();
174 var type = nodeTemplateEditedReqOrCap.children(".type").children("a").data("qname");
175 var propertiesContainer = nodeTemplateEditedReqOrCap.children(".propertiesContainer");
180 $("#${shortName}Id").val(id);
183 // we use the type as key at NameChooser. We hope that there are no duplicates. Otherwise, update won't work.
184 $("#${shortName}NameChooser").select2("val", type);
185 // make consistency check
186 var data = $("#${shortName}NameChooser").select2("data");
188 vShowError("type " + type + " could not be selected.")
189 } else if (name != (data.text)) {
190 vShowError("There are two names for different types. That case is not handled in the UI.");
194 $("#${shortName}TypeDisplay").val(type);
197 update${shortName}PropertiesContainerWithClone(propertiesContainer);
199 $("#add${shortName}btn").show();
200 $("#update${shortName}btn").hide();
201 $("#delete${shortName}btn").hide();
202 $("#headerAddOrUpdate").text("Add");
204 // QUICK HACK if dialog has been shown before -> show properties of selected type
205 if ($("#${shortName}NameChooser").select2("data") != null) {
206 update${shortName}PropertiesFromSelectedType();
210 $("#AddOrUpdate${shortName}Diag").modal("show");
216 * Called at click on button "Add" or "Change"
218 function addOrUpdate${shortName}(update) {
219 if (highlightRequiredFields()) {
220 vShowError("Please fill in all required fields");
223 require(["tmpl"], function(tmpl) {
224 // Generate skeletton div
225 var sel2data = $("#${shortName}NameChooser").select2("data");
227 id: $("#${shortName}Id").val(),
231 // tmpl-${shortName} is defined in reqsorcaps.tag
232 var div = tmpl("tmpl-${shortName}", data);
234 // Add the div to the node template
236 nodeTemplateEditedReqOrCap.replaceWith(div);
238 selectedNodeTemplateForReqCapAddition.children(".${cssClassPrefix}Container").children(".content").children(".addnewreqorcap").before(div);
241 // Put properties at the right place
242 $("#toBeReplacedByProperties").replaceWith($("#${shortName}PropertiesContainer").children());
244 $("#AddOrUpdate${shortName}Diag").modal("hide");