Init form feature.
This commit is contained in:
parent
852411e569
commit
23001f9921
10 changed files with 439 additions and 4 deletions
|
@ -0,0 +1,15 @@
|
||||||
|
class App.ChannelForm extends App.Controller
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
@title 'Form'
|
||||||
|
@render()
|
||||||
|
|
||||||
|
new App.SettingsArea(
|
||||||
|
el: @el.find('.js-settings')
|
||||||
|
area: 'Form::Base'
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
@html App.view('channel/form')(
|
||||||
|
baseurl: window.location.origin
|
||||||
|
)
|
|
@ -6,8 +6,9 @@
|
||||||
#App.Config.set( 'Channels', { prio: 2500, parent: '#admin', name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBar' )
|
#App.Config.set( 'Channels', { prio: 2500, parent: '#admin', name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBar' )
|
||||||
|
|
||||||
App.Config.set( 'Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: App.ChannelWeb, role: ['Admin'] }, 'NavBarAdmin' )
|
App.Config.set( 'Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: App.ChannelWeb, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
App.Config.set( 'Email', { prio: 2000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, role: ['Admin'] }, 'NavBarAdmin' )
|
App.Config.set( 'Form', { prio: 2000, name: 'Form', parent: '#channels', target: '#channels/form', controller: App.ChannelForm, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
App.Config.set( 'Chat', { prio: 3000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' )
|
App.Config.set( 'Email', { prio: 3000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
App.Config.set( 'Twitter', { prio: 4000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: App.ChannelTwitter, role: ['Admin'] }, 'NavBarAdmin' )
|
App.Config.set( 'Chat', { prio: 4000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
App.Config.set( 'Facebook', { prio: 5000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarAdmin' )
|
App.Config.set( 'Twitter', { prio: 5000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: App.ChannelTwitter, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
App.Config.set( 'Facebook', { prio: 6000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarAdmin' )
|
||||||
|
|
||||||
|
|
42
app/assets/javascripts/app/views/channel/form.jst.eco
Normal file
42
app/assets/javascripts/app/views/channel/form.jst.eco
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="page-header-title">
|
||||||
|
<h1><%- @T('Form') %> <small></small></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p><%- @T('With form you can add a formular to your web page witch directly generates a Ticket for you.') %></p>
|
||||||
|
|
||||||
|
<div class="js-settings"></div>
|
||||||
|
|
||||||
|
<h2><%- @T('Settings') %></h2>
|
||||||
|
<table class="settings-list">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="white-space: nowrap;"><%- @T('Option') %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><label><input type="checkbox" name="debug"/> <%- @T('Debug') %></label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label><input type="checkbox" name="modal"/> <%- @T('Modal Dialog') %></label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label><input type="checkbox"/> <%- @T('Debug') %></label></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p><%- @T('You need to add the following Java Script code snipped to your web page') %>:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<script id="zammad_form_script" src="<%= @baseurl %>/assets/form/form.js"></script>
|
||||||
|
<script>
|
||||||
|
$('#feedback-form').zammad_form({
|
||||||
|
lang: 'de-de',
|
||||||
|
debug: true,
|
||||||
|
modal: false,
|
||||||
|
});
|
||||||
|
</script></pre>
|
||||||
|
</div>
|
99
app/controllers/form_controller.rb
Normal file
99
app/controllers/form_controller.rb
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class FormController < ApplicationController
|
||||||
|
|
||||||
|
def config
|
||||||
|
return if !enabled?
|
||||||
|
|
||||||
|
api_path = Rails.configuration.api_path
|
||||||
|
http_type = Setting.get('http_type')
|
||||||
|
fqdn = Setting.get('fqdn')
|
||||||
|
|
||||||
|
endpoint = "#{http_type}://#{fqdn}#{api_path}/form_submit"
|
||||||
|
|
||||||
|
config = {
|
||||||
|
enabled: Setting.get('form_ticket_create'),
|
||||||
|
endpoint: endpoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
render json: config, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit
|
||||||
|
return if !enabled?
|
||||||
|
|
||||||
|
# validate input
|
||||||
|
errors = {}
|
||||||
|
if !params[:name] || params[:name].empty?
|
||||||
|
errors['name'] = 'required'
|
||||||
|
end
|
||||||
|
if !params[:email] || params[:email].empty?
|
||||||
|
errors['email'] = 'required'
|
||||||
|
end
|
||||||
|
if params[:email] !~ /@/
|
||||||
|
errors['email'] = 'invalid'
|
||||||
|
end
|
||||||
|
if !params[:body] || params[:body].empty?
|
||||||
|
errors['body'] = 'required'
|
||||||
|
end
|
||||||
|
|
||||||
|
if errors && !errors.empty?
|
||||||
|
render json: {
|
||||||
|
errors: errors
|
||||||
|
}, status: :ok
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
name = params[:name].strip
|
||||||
|
email = params[:email].strip.downcase
|
||||||
|
|
||||||
|
customer = User.find_by(email: email)
|
||||||
|
if !customer
|
||||||
|
roles = Role.where( name: 'Customer' )
|
||||||
|
customer = User.create(
|
||||||
|
firstname: name,
|
||||||
|
lastname: '',
|
||||||
|
email: email,
|
||||||
|
password: '',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
ticket = Ticket.create(
|
||||||
|
group_id: 1,
|
||||||
|
customer_id: customer.id,
|
||||||
|
title: '',
|
||||||
|
state_id: Ticket::State.find_by( name: 'new' ).id,
|
||||||
|
priority_id: Ticket::Priority.find_by( name: '2 normal' ).id,
|
||||||
|
updated_by_id: customer.id,
|
||||||
|
created_by_id: customer.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
article = Ticket::Article.create(
|
||||||
|
ticket_id: ticket.id,
|
||||||
|
type_id: Ticket::Article::Type.find_by( name: 'web' ).id,
|
||||||
|
sender_id: Ticket::Article::Sender.find_by( name: 'Customer' ).id,
|
||||||
|
body: params[:body],
|
||||||
|
from: email,
|
||||||
|
subject: '',
|
||||||
|
internal: false,
|
||||||
|
updated_by_id: customer.id,
|
||||||
|
created_by_id: customer.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def enabled?
|
||||||
|
return true if Setting.get('form_ticket_create')
|
||||||
|
response_access_deny
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
8
config/routes/form.rb
Normal file
8
config/routes/form.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Zammad::Application.routes.draw do
|
||||||
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
|
# forms
|
||||||
|
match api_path + '/form_submit', to: 'form#submit', via: :post
|
||||||
|
match api_path + '/form_config', to: 'form#config', via: :get
|
||||||
|
|
||||||
|
end
|
30
db/migrate/20150810000001_update_form.rb
Normal file
30
db/migrate/20150810000001_update_form.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
class UpdateForm < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Enable Ticket creation',
|
||||||
|
name: 'form_ticket_create',
|
||||||
|
area: 'Form::Base',
|
||||||
|
description: 'Defines if ticket can get created via web form.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: true,
|
||||||
|
name: 'form_ticket_create',
|
||||||
|
tag: 'boolean',
|
||||||
|
options: {
|
||||||
|
true => 'yes',
|
||||||
|
false => 'no',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: false,
|
||||||
|
frontend: false,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
23
db/seeds.rb
23
db/seeds.rb
|
@ -992,6 +992,29 @@ Setting.create_if_not_exists(
|
||||||
frontend: true
|
frontend: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Enable Ticket creation',
|
||||||
|
name: 'form_ticket_create',
|
||||||
|
area: 'Form::Base',
|
||||||
|
description: 'Defines if ticket can get created via web form.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: true,
|
||||||
|
name: 'form_ticket_create',
|
||||||
|
tag: 'boolean',
|
||||||
|
options: {
|
||||||
|
true => 'yes',
|
||||||
|
false => 'no',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: false,
|
||||||
|
frontend: false,
|
||||||
|
)
|
||||||
|
|
||||||
Setting.create_if_not_exists(
|
Setting.create_if_not_exists(
|
||||||
title: 'Sender Format',
|
title: 'Sender Format',
|
||||||
name: 'ticket_define_email_from',
|
name: 'ticket_define_email_from',
|
||||||
|
|
19
public/assets/form/form.css
Normal file
19
public/assets/form/form.css
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.zammad-form {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zammad-form .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zammad-form .form-control {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zammad-form .has-error .form-control {
|
||||||
|
border-color: #a94442;
|
||||||
|
}
|
||||||
|
.zammad-form .has-error label {
|
||||||
|
color: #a94442;
|
||||||
|
}
|
19
public/assets/form/form.html
Normal file
19
public/assets/form/form.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Example Form</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="example_form"></div>
|
||||||
|
|
||||||
|
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
|
||||||
|
<script id="zammad_form_script" src="http://localhost:3000/assets/form/form.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#example_form').zammad_form({debug:true});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
179
public/assets/form/form.js
Normal file
179
public/assets/form/form.js
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
(function ($) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
provides feedback form for zammad
|
||||||
|
*/
|
||||||
|
|
||||||
|
var pluginName = 'zammad_form',
|
||||||
|
defaults = {
|
||||||
|
debug: false,
|
||||||
|
loadCss: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
function Plugin( element, options ) {
|
||||||
|
this.element = element;
|
||||||
|
this.$element = $(element)
|
||||||
|
|
||||||
|
this.options = $.extend( {}, defaults, options) ;
|
||||||
|
|
||||||
|
this._defaults = defaults;
|
||||||
|
this._name = pluginName;
|
||||||
|
|
||||||
|
this._endpoint_config = '/api/v1/form_config'
|
||||||
|
this._script_location = '/assets/form/form.js'
|
||||||
|
|
||||||
|
this._config = {}
|
||||||
|
|
||||||
|
this.attributes = [
|
||||||
|
{
|
||||||
|
display: 'Name',
|
||||||
|
name: 'name',
|
||||||
|
tag: 'input',
|
||||||
|
type: 'text',
|
||||||
|
placeholder: 'Your Name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: 'Email',
|
||||||
|
name: 'email',
|
||||||
|
tag: 'input',
|
||||||
|
type: 'email',
|
||||||
|
placeholder: 'Your Email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display: 'Message',
|
||||||
|
name: 'body',
|
||||||
|
tag: 'textarea',
|
||||||
|
placeholder: 'Your Message...',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Plugin.prototype.init = function () {
|
||||||
|
var _this = this,
|
||||||
|
src = document.getElementById("zammad_form_script").src,
|
||||||
|
endpoint_config = src.replace(this._script_location, this._endpoint_config)
|
||||||
|
|
||||||
|
_this.log('init')
|
||||||
|
|
||||||
|
if (_this.options.loadCss) {
|
||||||
|
_this.loadCss('form.css')
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.log('endpoint_config: ' + endpoint_config)
|
||||||
|
|
||||||
|
// load config
|
||||||
|
$.ajax({
|
||||||
|
url: endpoint_config,
|
||||||
|
}).done(function(data) {
|
||||||
|
_this.log('config:', data)
|
||||||
|
_this._config = data
|
||||||
|
_this.render()
|
||||||
|
}).fail(function() {
|
||||||
|
alert('Faild to load form config!')
|
||||||
|
});
|
||||||
|
|
||||||
|
// bind form submit
|
||||||
|
this.$element.on('submit', function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
_this.submit()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// load css
|
||||||
|
Plugin.prototype.loadCss = function(filename) {
|
||||||
|
if (document.createStyleSheet) {
|
||||||
|
document.createStyleSheet(filename)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('<link rel="stylesheet" type="text/css" href="' + filename + '" />').appendTo('head')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send
|
||||||
|
Plugin.prototype.submit = function() {
|
||||||
|
var _this = this
|
||||||
|
|
||||||
|
_this.log('submit form', _this.getParams())
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: 'post',
|
||||||
|
url: _this._config.endpoint,
|
||||||
|
data: _this.getParams(),
|
||||||
|
}).done(function(data) {
|
||||||
|
_this.log('ok done', _this._config.endpoint)
|
||||||
|
|
||||||
|
// removed errors
|
||||||
|
_this.$element.find('.has-error').removeClass('has-error')
|
||||||
|
|
||||||
|
// set errors
|
||||||
|
if (data.errors) {
|
||||||
|
$.each(data.errors, function( key, value ) {
|
||||||
|
_this.$element.find('[name=' + key + ']').closest('.form-group').addClass('has-error')
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ticket has been created
|
||||||
|
_this.thanks()
|
||||||
|
}).fail(function() {
|
||||||
|
alert('Faild to submit form!')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// get params
|
||||||
|
Plugin.prototype.getParams = function() {
|
||||||
|
var _this = this,
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
$.each( _this.$element.find('form').serializeArray(), function( index, item ) {
|
||||||
|
params[item.name] = item.value
|
||||||
|
})
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
// render form
|
||||||
|
Plugin.prototype.render = function(e) {
|
||||||
|
var form = $('<form class="zammad-form"></form>')
|
||||||
|
$.each(this.attributes, function( index, value ) {
|
||||||
|
var item = $('<div class="form-group"><label>' + value.display + '</label></div>')
|
||||||
|
if (value.tag == 'input') {
|
||||||
|
item.append('<input class="form-control" name="' + value.name + '" type="' + value.type + '" placeholder="' + value.placeholder + '">')
|
||||||
|
}
|
||||||
|
else if (value.tag == 'textarea') {
|
||||||
|
item.append('<textarea class="form-control" name="' + value.name + '" placeholder="' + value.placeholder + '"></textarea>')
|
||||||
|
}
|
||||||
|
form.append(item)
|
||||||
|
})
|
||||||
|
form.append('<button type="submit">' + 'Submit' + '</button')
|
||||||
|
this.$element.html(form)
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
|
||||||
|
// thanks
|
||||||
|
Plugin.prototype.thanks = function(e) {
|
||||||
|
var form = $('<div>Thank you for your inquery!</div>')
|
||||||
|
this.$element.html(form)
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
|
||||||
|
// log method
|
||||||
|
Plugin.prototype.log = function() {
|
||||||
|
if (this.options.debug) {
|
||||||
|
console.log(this._name, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn[pluginName] = function ( options ) {
|
||||||
|
return this.each(function () {
|
||||||
|
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||||
|
$.data(this, 'plugin_' + pluginName,
|
||||||
|
new Plugin( this, options ));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}(jQuery));
|
Loading…
Reference in a new issue