Przeglądaj źródła

support for non GET methods. Closes #15

bubble
Ayush Gupta 12 lat temu
rodzic
commit
f2e63c65a7
14 zmienionych plików z 239 dodań i 37 usunięć
  1. +11
    -1
      README.md
  2. +5
    -0
      dist/css/screen.css
  3. +2
    -1
      dist/index.html
  4. +5
    -0
      dist/lib/swagger.js
  5. +160
    -24
      dist/swagger-ui.js
  6. +1
    -1
      dist/swagger-ui.min.js
  7. +5
    -0
      lib/swagger.js
  8. +13
    -2
      src/main/coffeescript/view/OperationView.coffee
  9. +2
    -0
      src/main/coffeescript/view/ParameterView.coffee
  10. +5
    -0
      src/main/html/css/screen.css
  11. +2
    -1
      src/main/html/index.html
  12. +2
    -1
      src/main/template/operation.handlebars
  13. +14
    -3
      src/main/template/param.handlebars
  14. +12
    -3
      src/main/template/param_required.handlebars

+ 11
- 1
README.md Wyświetl plik

@@ -32,8 +32,18 @@ You may choose to customize Swagger UI for your organization. Here is an overvie
- src/main/html: the html files, some images and css
- src/main/javascript: some legacy javascript referenced by CofffeeScript code

### HTTP Methods and API Invocation
swagger-ui supports invocation of all HTTP methods APIs but only GET methods APIs are enabled by default. You can choose to enable other HTTP methods like POST, PUT and DELETE. This can be enabled by setting the supportedSubmitMethods parameter when creating SwaggerUI instance.

For example if you wanted to enable GET, POST and PUT but not for DELETE, you'd set this as:

```supportedSubmitMethods: ['get', 'post', 'put']
```

_Note that for POST/PUT body, you'd need to paste in the request data in an appropriate format which your service can unmarshall_

### Header Parameters
Because of [Cross-Origin Resource Sharing](http://www.w3.org/TR/cors/) restrictions, swagger-ui, by default, does not send header parameters. This can be enabled by [setting the supportHeaderParams to false when creating SwaggerUI instance](https://github.com/wordnik/swagger-ui/blob/overhaul/src/main/html/index.html#L45).
header parameters aere supported. However because of [Cross-Origin Resource Sharing](http://www.w3.org/TR/cors/) restrictions, swagger-ui, by default, does not send header parameters. This can be enabled by [setting the supportHeaderParams to false when creating SwaggerUI instance](https://github.com/wordnik/swagger-ui/blob/overhaul/src/main/html/index.html#L45).





+ 5
- 0
dist/css/screen.css Wyświetl plik

@@ -104,6 +104,11 @@ div.heading_with_menu {
box-sizing: border-box;
margin-top: 10px; }

.body-textarea {
width: 300px;
height: 100px;
}

p {
line-height: 1.4em;
padding: 0 0 10px 0;


+ 2
- 1
dist/index.html Wyświetl plik

@@ -45,7 +45,8 @@
discoveryUrl:"http://petstore.swagger.wordnik.com/api/resources.json",
apiKey:"special-key",
dom_id:"swagger-ui-container",
supportHeaderParams: false
supportHeaderParams: false,
supportedSubmitMethods: ['get', 'post', 'put']
});

window.swaggerUi.load();


+ 5
- 0
dist/lib/swagger.js Wyświetl plik

@@ -35,6 +35,7 @@
this.verbose = options.verbose;
}
this.supportHeaderParams = options.supportHeaderParams != null ? options.supportHeaderParams : false;
this.supportedSubmitMethods = options.supportedSubmitMethods != null ? options.supportedSubmitMethods : ['get'];
if (options.success != null) {
this.success = options.success;
}
@@ -371,6 +372,10 @@
return this.resource.api.supportHeaderParams;
};

SwaggerOperation.prototype.supportedSubmitMethods = function() {
return this.resource.api.supportedSubmitMethods;
};

SwaggerOperation.prototype.getQueryAndHeaderParams = function(args, includeApiKey) {
if (includeApiKey == null) {
includeApiKey = true;


+ 160
- 24
dist/swagger-ui.js Wyświetl plik

@@ -191,6 +191,11 @@ function program1(depth0,data) {
function program3(depth0,data) {
return "\n ";}

function program5(depth0,data) {
return "\n <div class='sandbox_header'>\n <input class='submit' name='commit' type='button' value='Try it out!' />\n <a href='#' class='response_hider' style='display:none'>Hide Response</a>\n <img alt='Throbber' class='response_throbber' src='http://swagger.wordnik.com/images/throbber.gif' style='display:none' />\n </div>\n ";}

buffer += "\n <ul class='operations' >\n <li class='";
@@ -299,13 +304,13 @@ function program3(depth0,data) {
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n <form accept-charset='UTF-8' action='#' class='sandbox' method='post'>\n <div style='margin:0;padding:0;display:inline'></div>\n <h4>Parameters</h4>\n <table class='fullwidth'>\n <thead>\n <tr>\n <th>Parameter</th>\n <th>Value</th>\n <th>Description</th>\n </tr>\n </thead>\n <tbody class=\"operation-params\">\n\n </tbody>\n </table>\n ";
foundHelper = helpers.isGetMethod;
stack1 = foundHelper || depth0.isGetMethod;
foundHelper = helpers.isReadOnly;
stack1 = foundHelper || depth0.isReadOnly;
stack2 = helpers['if'];
tmp1 = self.program(3, program3, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.noop;
tmp1.inverse = self.program(5, program5, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n </form>\n <div class='response' style='display:none'>\n <h4>Request URL</h4>\n <div class='block request_url'></div>\n <h4>Response Body</h4>\n <div class='block response_body'></div>\n <h4>Response Code</h4>\n <div class='block response_code'></div>\n <h4>Response Headers</h4>\n <div class='block response_headers'></div>\n </div>\n </div>\n </li>\n </ul>\n";
@@ -320,47 +325,104 @@ templates['param'] = template(function (Handlebars,depth0,helpers,partials,data)

function program1(depth0,data) {
var buffer = "", stack1, stack2;
buffer += "\n ";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
stack2 = helpers['if'];
tmp1 = self.program(2, program2, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(4, program4, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n \n ";
return buffer;}
function program2(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input minlength='0' name='";
buffer += "\n <textarea class='body-textarea' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "' placeholder='' type='text' value='";
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "defaultValue", { hash: {} }); }
buffer += escapeExpression(stack1) + "'/>\n ";
buffer += escapeExpression(stack1) + "</textarea>\n ";
return buffer;}

function program3(depth0,data) {
function program4(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input minlength='0' name='";
buffer += "\n <textarea class='body-textarea' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "' placeholder='' type='text' value=''/>\n ";
buffer += escapeExpression(stack1) + "'></textarea>\n ";
return buffer;}

buffer += "<td class='code'>";
function program6(depth0,data) {
var buffer = "", stack1, stack2;
buffer += "\n ";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
stack2 = helpers['if'];
tmp1 = self.program(7, program7, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(9, program9, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n ";
return buffer;}
function program7(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input minlength='0' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "</td>\n<td>\n ";
buffer += escapeExpression(stack1) + "' placeholder='' type='text' value='";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "defaultValue", { hash: {} }); }
buffer += escapeExpression(stack1) + "'/>\n ";
return buffer;}

function program9(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input minlength='0' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "' placeholder='' type='text' value=''/>\n ";
return buffer;}

buffer += "<td class='code'>";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "</td>\n<td>\n \n ";
foundHelper = helpers.isBody;
stack1 = foundHelper || depth0.isBody;
stack2 = helpers['if'];
tmp1 = self.program(1, program1, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(3, program3, data);
tmp1.inverse = self.program(6, program6, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n</td>\n<td width='500'>";
buffer += "\n\n</td>\n<td width='500'>";
foundHelper = helpers.description;
stack1 = foundHelper || depth0.description;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
@@ -542,8 +604,65 @@ templates['param_required'] = template(function (Handlebars,depth0,helpers,parti

function program1(depth0,data) {
var buffer = "", stack1, stack2;
buffer += "\n ";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
stack2 = helpers['if'];
tmp1 = self.program(2, program2, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(4, program4, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n \n ";
return buffer;}
function program2(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input class='required' minlength='1' name='";
buffer += "\n <textarea class='body-textarea' placeholder='(required)' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "defaultValue", { hash: {} }); }
buffer += escapeExpression(stack1) + "</textarea>\n ";
return buffer;}

function program4(depth0,data) {
var buffer = "", stack1;
buffer += "\n <textarea class='body-textarea' placeholder='(required)' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "'></textarea>\n ";
return buffer;}

function program6(depth0,data) {
var buffer = "", stack1, stack2;
buffer += "\n ";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
stack2 = helpers['if'];
tmp1 = self.program(7, program7, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(9, program9, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n ";
return buffer;}
function program7(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input class='required' minlength='1' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
@@ -553,18 +672,18 @@ function program1(depth0,data) {
stack1 = foundHelper || depth0.defaultValue;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "defaultValue", { hash: {} }); }
buffer += escapeExpression(stack1) + "'/>\n ";
buffer += escapeExpression(stack1) + "'/>\n ";
return buffer;}

function program3(depth0,data) {
function program9(depth0,data) {
var buffer = "", stack1;
buffer += "\n <input class='required' minlength='1' name='";
buffer += "\n <input class='required' minlength='1' name='";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "' placeholder='(required)' type='text' value=''/>\n ";
buffer += escapeExpression(stack1) + "' placeholder='(required)' type='text' value=''/>\n ";
return buffer;}

buffer += "<td class='code required'>";
@@ -573,13 +692,13 @@ function program3(depth0,data) {
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "</td>\n<td>\n ";
foundHelper = helpers.defaultValue;
stack1 = foundHelper || depth0.defaultValue;
foundHelper = helpers.isBody;
stack1 = foundHelper || depth0.isBody;
stack2 = helpers['if'];
tmp1 = self.program(1, program1, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.program(3, program3, data);
tmp1.inverse = self.program(6, program6, data);
stack1 = stack2.call(depth0, stack1, tmp1);
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n</td>\n<td width='500'>\n <strong>";
@@ -935,7 +1054,11 @@ templates['resource'] = template(function (Handlebars,depth0,helpers,partials,da
OperationView.prototype.initialize = function() {};

OperationView.prototype.render = function() {
var param, _i, _len, _ref;
var isMethodSubmissionSupported, param, _i, _len, _ref;
isMethodSubmissionSupported = jQuery.inArray(this.model.httpMethod, this.model.supportedSubmitMethods()) >= 0;
if (!isMethodSubmissionSupported) {
this.model.isReadOnly = true;
}
$(this.el).html(Handlebars.templates.operation(this.model));
_ref = this.model.parameters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -950,13 +1073,13 @@ templates['resource'] = template(function (Handlebars,depth0,helpers,partials,da
paramView = new ParameterView({
model: param,
tagName: 'tr',
readOnly: !this.model.isGetMethod
readOnly: this.model.isReadOnly
});
return $('.operation-params', $(this.el)).append(paramView.render().el);
};

OperationView.prototype.submitOperation = function() {
var error_free, form, headerParams, invocationUrl, map, o, obj, _i, _len, _ref,
var bodyParam, error_free, form, headerParams, invocationUrl, map, o, obj, param, _i, _j, _len, _len1, _ref, _ref1,
_this = this;
form = $('.sandbox', $(this.el));
error_free = true;
@@ -982,6 +1105,15 @@ templates['resource'] = template(function (Handlebars,depth0,helpers,partials,da
map[o.name] = o.value;
}
}
bodyParam = null;
_ref1 = this.model.parameters;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
param = _ref1[_j];
if (param.paramType === 'body') {
bodyParam = map[param.name];
}
}
log("bodyParam = " + bodyParam);
headerParams = null;
invocationUrl = this.model.supportHeaderParams() ? (headerParams = this.model.getHeaderParams(map), this.model.urlify(map, false)) : this.model.urlify(map, true);
log('submitting ' + invocationUrl);
@@ -991,6 +1123,7 @@ templates['resource'] = template(function (Handlebars,depth0,helpers,partials,da
type: this.model.httpMethod,
url: invocationUrl,
headers: headerParams,
data: bodyParam,
dataType: 'json',
error: function(xhr, textStatus, error) {
return _this.showErrorStatus(xhr, textStatus, error);
@@ -1074,6 +1207,9 @@ templates['resource'] = template(function (Handlebars,depth0,helpers,partials,da

ParameterView.prototype.render = function() {
var template;
if (this.model.paramType === 'body') {
this.model.isBody = true;
}
template = this.template();
$(this.el).html(template(this.model));
return this;


+ 1
- 1
dist/swagger-ui.min.js
Plik diff jest za duży
Wyświetl plik


+ 5
- 0
lib/swagger.js Wyświetl plik

@@ -35,6 +35,7 @@
this.verbose = options.verbose;
}
this.supportHeaderParams = options.supportHeaderParams != null ? options.supportHeaderParams : false;
this.supportedSubmitMethods = options.supportedSubmitMethods != null ? options.supportedSubmitMethods : ['get'];
if (options.success != null) {
this.success = options.success;
}
@@ -371,6 +372,10 @@
return this.resource.api.supportHeaderParams;
};

SwaggerOperation.prototype.supportedSubmitMethods = function() {
return this.resource.api.supportedSubmitMethods;
};

SwaggerOperation.prototype.getQueryAndHeaderParams = function(args, includeApiKey) {
if (includeApiKey == null) {
includeApiKey = true;


+ 13
- 2
src/main/coffeescript/view/OperationView.coffee Wyświetl plik

@@ -8,6 +8,9 @@ class OperationView extends Backbone.View
initialize: ->

render: ->
isMethodSubmissionSupported = jQuery.inArray(@model.httpMethod, @model.supportedSubmitMethods()) >= 0
@model.isReadOnly = true unless isMethodSubmissionSupported

$(@el).html(Handlebars.templates.operation(@model))

# Render each parameter
@@ -16,9 +19,10 @@ class OperationView extends Backbone.View

addParameter: (param) ->
# Render a parameter
paramView = new ParameterView({model: param, tagName: 'tr', readOnly: !@model.isGetMethod})
paramView = new ParameterView({model: param, tagName: 'tr', readOnly: @model.isReadOnly})
$('.operation-params', $(@el)).append paramView.render().el

submitOperation: ->
# Check for errors
form = $('.sandbox', $(@el))
@@ -38,6 +42,13 @@ class OperationView extends Backbone.View
if(o.value? && jQuery.trim(o.value).length > 0)
map[o.name] = o.value

bodyParam = null
for param in @model.parameters
if param.paramType is 'body'
bodyParam = map[param.name]

log "bodyParam = " + bodyParam

headerParams = null
invocationUrl =
if @model.supportHeaderParams()
@@ -56,7 +67,7 @@ class OperationView extends Backbone.View
type: @model.httpMethod
url: invocationUrl
headers: headerParams
# data: JSON.stringify(@body)
data: bodyParam
dataType: 'json'
error: (xhr, textStatus, error) =>
@showErrorStatus(xhr, textStatus, error)


+ 2
- 0
src/main/coffeescript/view/ParameterView.coffee Wyświetl plik

@@ -2,6 +2,8 @@ class ParameterView extends Backbone.View
initialize: ->

render: ->
@model.isBody = true if @model.paramType == 'body'

template = @template()
$(@el).html(template(@model))
@


+ 5
- 0
src/main/html/css/screen.css Wyświetl plik

@@ -104,6 +104,11 @@ div.heading_with_menu {
box-sizing: border-box;
margin-top: 10px; }

.body-textarea {
width: 300px;
height: 100px;
}

p {
line-height: 1.4em;
padding: 0 0 10px 0;


+ 2
- 1
src/main/html/index.html Wyświetl plik

@@ -45,7 +45,8 @@
discoveryUrl:"http://petstore.swagger.wordnik.com/api/resources.json",
apiKey:"special-key",
dom_id:"swagger-ui-container",
supportHeaderParams: false
supportHeaderParams: false,
supportedSubmitMethods: ['get', 'post', 'put']
});

window.swaggerUi.load();


+ 2
- 1
src/main/template/operation.handlebars Wyświetl plik

@@ -36,7 +36,8 @@

</tbody>
</table>
{{#if isGetMethod}}
{{#if isReadOnly}}
{{else}}
<div class='sandbox_header'>
<input class='submit' name='commit' type='button' value='Try it out!' />
<a href='#' class='response_hider' style='display:none'>Hide Response</a>


+ 14
- 3
src/main/template/param.handlebars Wyświetl plik

@@ -1,10 +1,21 @@
<td class='code'>{{name}}</td>
<td>
{{#if defaultValue}}
<input minlength='0' name='{{name}}' placeholder='' type='text' value='{{defaultValue}}'/>
{{#if isBody}}
{{#if defaultValue}}
<textarea class='body-textarea' name='{{name}}'>{{defaultValue}}</textarea>
{{else}}
<textarea class='body-textarea' name='{{name}}'></textarea>
{{/if}}
{{else}}
<input minlength='0' name='{{name}}' placeholder='' type='text' value=''/>
{{#if defaultValue}}
<input minlength='0' name='{{name}}' placeholder='' type='text' value='{{defaultValue}}'/>
{{else}}
<input minlength='0' name='{{name}}' placeholder='' type='text' value=''/>
{{/if}}
{{/if}}

</td>
<td width='500'>{{description}}</td>


+ 12
- 3
src/main/template/param_required.handlebars Wyświetl plik

@@ -1,9 +1,18 @@
<td class='code required'>{{name}}</td>
<td>
{{#if defaultValue}}
<input class='required' minlength='1' name='{{name}}' placeholder='(required)' type='text' value='{{defaultValue}}'/>
{{#if isBody}}
{{#if defaultValue}}
<textarea class='body-textarea' placeholder='(required)' name='{{name}}'>{{defaultValue}}</textarea>
{{else}}
<textarea class='body-textarea' placeholder='(required)' name='{{name}}'></textarea>
{{/if}}
{{else}}
<input class='required' minlength='1' name='{{name}}' placeholder='(required)' type='text' value=''/>
{{#if defaultValue}}
<input class='required' minlength='1' name='{{name}}' placeholder='(required)' type='text' value='{{defaultValue}}'/>
{{else}}
<input class='required' minlength='1' name='{{name}}' placeholder='(required)' type='text' value=''/>
{{/if}}
{{/if}}
</td>
<td width='500'>


Ładowanie…
Anuluj
Zapisz