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( '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( 'Chat', { prio: 3000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, 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( 'Facebook', { prio: 5000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, 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( 'Email', { prio: 3000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, 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( '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
|
||||
)
|
||||
|
||||
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(
|
||||
title: 'Sender Format',
|
||||
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