Init form feature.

This commit is contained in:
Martin Edenhofer 2015-08-10 02:10:41 +02:00
parent 852411e569
commit 23001f9921
10 changed files with 439 additions and 4 deletions

View file

@ -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
)

View file

@ -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' )

View 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>
&lt;script id="zammad_form_script" src="<%= @baseurl %>/assets/form/form.js"&gt;&lt;/script&gt;
&lt;script&gt;
$('#feedback-form').zammad_form({
lang: 'de-de',
debug: true,
modal: false,
});
&lt;/script&gt;</pre>
</div>

View 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
View 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

View 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

View file

@ -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',

View 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;
}

View 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
View 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));