Node creation, required form field styling, notification and error popups, JSDE hooks and window-contained form hooking, bugfix in form hooking, icon replacement for form submission, improve form hooking callback signature, include jQuery timing plugin

feature/core
Sven Slootweg 11 years ago
parent e73e5d970e
commit 59761e6412

@ -23,5 +23,51 @@ if($router->uMethod == "get")
elseif($router->uMethod == "post") elseif($router->uMethod == "post")
{ {
/* Process form */ /* Process form */
$sErrors = array();
if(empty($_POST['name']))
{
$sErrors[] = "You must enter a name for the new node. This name does not have to be unique.";
}
if(empty($sErrors))
{
$sNode = new Node();
$sNode->uName = $_POST['name'];
$sNode->uNotes = $_POST['notes'];
$sNode->uTypeId = 0;
$sNode->uParentRevisionId = 0;
$sNode->uFirstRevisionId = 0;
$sNode->uUserId = 0;
$sNode->uCreationDate = time();
$sNode->uLatestRevision = true;
$sNode->InsertIntoDatabase();
/* Update the entry to refer to itself as the first revision */
$sNode->uFirstRevisionId = $sNode->sId;
$sNode->InsertIntoDatabase();
$sData = array(
"result" => "success",
"message" => "Node '" . htmlspecialchars($_POST['name']) . "' created.",
"node_id" => $sNode->sId
);
}
else
{
$sErrorList = "";
foreach($sErrors as $sError)
{
$sErrorList .= "<li>{$sError}</li>";
}
$sData = array(
"result" => "error",
"message" => "One or more form fields were not filled in correctly: <ul>{$sErrorList}</ul>"
);
}
} }

@ -162,3 +162,79 @@ textarea
bottom: 0px; bottom: 0px;
text-align: right; text-align: right;
} }
i.required
{
font-size: 10px;
margin-left: 4px;
color: rgb(159,68,74);
float: right;
margin-right: 7px;
margin-top: 2px;
}
i.error, i.notification
{
font-size: 19px;
margin-right: 9px !important;
}
i.error
{
color: #FFD2D2;
}
i.notification
{
color: #CBCAFF;
}
#notification_area
{
position: absolute;
right: 0px;
bottom: 32px;
z-index: 2147483640;
}
.notification-header
{
margin-right: 6px;
font-weight: bold;
}
.notification-popup, .error-popup
{
text-align: right;
}
.notification-popup .notification-contents, .error-popup .notification-contents
{
text-align: left;
display: inline-block;
border-radius: 6px;
margin-right: 19px;
margin-top: 10px;
padding: 9px 14px;
color: white;
font-size: 15px;
filter: alpha(opacity=85);
opacity: 0.85;
width: auto;
}
.notification-popup .notification-contents
{
background-color: #2D2D2D;
}
.error-popup .notification-contents
{
background-color: #371B1B;
}
.notification-popup ul, .error-popup ul
{
margin: 4px 0px;
padding-left: 48px;
}

File diff suppressed because one or more lines are too long

@ -114,6 +114,11 @@ function JsdeWindow(options)
} }
this.BringToForeground(); this.BringToForeground();
if(typeof jsde_creation_hook === "function")
{
jsde_creation_hook(this);
}
} }
JsdeWindow.prototype.BringToForeground = function() JsdeWindow.prototype.BringToForeground = function()
@ -173,8 +178,14 @@ JsdeWindow.prototype.SetSize = function(width, height)
JsdeWindow.prototype.SetContents = function(html) JsdeWindow.prototype.SetContents = function(html)
{ {
console.log("set contents", html, this); var returnval = $(this._inner).html(html);
return $(this._inner).html(html);
if(typeof jsde_contents_hook === "function")
{
jsde_contents_hook(this);
}
return returnval;
} }
JsdeWindow.prototype.SetTitle = function(html) JsdeWindow.prototype.SetTitle = function(html)

@ -1,3 +1,20 @@
var jsde_creation_hook = function(win)
{
/* This function is a hook that is called after each creation of
* a JSDE window. */
}
var jsde_contents_hook = function(win)
{
/* This function is a hook that is called after each time
* content is set in a JSDE window. */
placeHooksForWindow(win);
}
notification_popups = [];
error_popups = [];
function hookSubmitEvent(form, callback, error) function hookSubmitEvent(form, callback, error)
{ {
/* Hooks a form to be submitted via AJAX, executing the given /* Hooks a form to be submitted via AJAX, executing the given
@ -11,18 +28,48 @@ function hookSubmitEvent(form, callback, error)
form.each(function(index){ form.each(function(index){
var element = $(this); var element = $(this);
var method = element.attr("method").toUpperCase(); var method = element.attr("method");
var target = element.attr("action"); var target = element.attr("action");
if(typeof method !== "undefined")
{
method = method.toUpperCase();
}
else
{
method = "GET";
}
element.submit(function(){ element.submit(function(){
var submit_button = element.find("button[type=submit]");
var submit_icon = submit_button.data("submit-icon");
if(typeof submit_icon !== "undefined")
{
/* First we will try to replace an existing icon
* in the button. If there is no icon yet, the
* entire contents of the button will be replaced
* with the submission icon. */
var current_icon = submit_button.find("i");
if(current_icon.length == 0)
{
submit_button.html("<span style='text-align: center;'><i></i></span>");
current_icon = element.find("i");
}
current_icon.removeClass().addClass(submit_icon);
}
var formdata = element.serialize(); var formdata = element.serialize();
console.log(formdata); console.log(formdata);
$.ajax({ $.ajax({
type: method, type: method,
url: target, url: target,
data: formdata, data: formdata,
success: callback, dataType: "json",
error: error success: function(data, xhr){ console.log(data); callback(element, data, xhr); },
error: function(data, xhr, err){ error(element, data, xhr, err); }
}); });
return false; return false;
@ -30,6 +77,69 @@ function hookSubmitEvent(form, callback, error)
}); });
} }
function placeHooksForWindow(win)
{
console.log();
$(win._outer).find("form").each(function(){
var callback = $(this).data("hook-callback");
if(typeof callback !== "undefined")
{
console.log("Hooking", this, "using callback", callback);
hookSubmitEvent($(this), window[callback]);
}
});
}
function callbackNodeCreated(form, data)
{
if(data.result == "success")
{
spawnNotification(data.message);
var node_id = data.node_id;
form.getWindow().Close();
new JsdeWindow({
width: 480,
height: 300,
x: 100,
y: 100,
title: "Node lookup",
contents: "Loading...",
source_url: "/nodes/" + node_id
});
}
else if(data.result == "error")
{
spawnError(data.message);
}
}
function spawnNotification(message)
{
var popup = spawnPopup(message, "notification");
notification_popups.push(popup);
}
function spawnError(message)
{
var popup = spawnPopup(message, "error");
error_popups.push(popup);
}
function spawnPopup(message, template)
{
var popup = $("#jsde_templates").find(".template_" + template).clone().removeClass("template_notification template_error");
popup.find(".message").html(message.replace("\n", "<br>"));
popup.hide();
popup.prependTo("#notification_area");
popup.fadeIn(300).wait(5000).fadeOut(400, $).remove();
return popup
}
$(function(){ $(function(){
hookSubmitEvent($("#form_search")); hookSubmitEvent($("#form_search"));
@ -56,4 +166,7 @@ $(function(){
contents: "Loading...", contents: "Loading...",
source_url: "/intro" source_url: "/intro"
}); });
spawnNotification("Test notification");
spawnError("Test error");
}); });

@ -5,6 +5,7 @@
<link rel="stylesheet" href="/static/css/jsde.base.css"> <link rel="stylesheet" href="/static/css/jsde.base.css">
<link rel="stylesheet" href="/static/css/jsde.style.css"> <link rel="stylesheet" href="/static/css/jsde.style.css">
<script src="/static/js/jquery-1.10.2.min.js"></script> <script src="/static/js/jquery-1.10.2.min.js"></script>
<script src="/static/js/jquery-timing.min.js"></script>
<script src="/static/js/jsde.js"></script> <script src="/static/js/jsde.js"></script>
<script src="/static/js/openng.js"></script> <script src="/static/js/openng.js"></script>
<style> <style>
@ -45,7 +46,7 @@
<form class="pure-form inline" id="form_search" method="post" action="/search"> <form class="pure-form inline" id="form_search" method="post" action="/search">
<span class="element-group"> <span class="element-group">
<input type="text" id="input_search_query" name="query" value="" placeholder="Enter something to search for..."> <input type="text" id="input_search_query" name="query" value="" placeholder="Enter something to search for...">
<button type="submit" class="pure-button search shadow"><i class="icon-search"></i>Search</button> <button type="submit" class="pure-button search shadow" data-submit-icon="icon-spinner icon-spin"><i class="icon-search"></i>Search</button>
<div class="clear"></div> <div class="clear"></div>
</span> </span>
</form> </form>
@ -57,6 +58,9 @@
</span> </span>
<a class="workspace-tab workspace-tab-add" id="workspace_tab_add" href="#">+</a> <a class="workspace-tab workspace-tab-add" id="workspace_tab_add" href="#">+</a>
</div> --> </div> -->
<div id="notification_area">
<!-- Notifications go here. -->
</div>
<div id="jsde_templates"> <div id="jsde_templates">
<div class="template_window window-wrapper window-styled"> <div class="template_window window-wrapper window-styled">
<div class="window-title"> <div class="window-title">
@ -76,6 +80,24 @@
</div> </div>
</div> </div>
</div> </div>
<div class="template_notification notification-popup">
<span class="notification-contents">
<span class="notification-header">
<i class="icon-info-sign pull-left notification"></i>
Notification
</span>
<span class="message"></span>
</span>
</div>
<div class="template_error error-popup">
<span class="notification-contents">
<span class="notification-header">
<i class="icon-remove-sign pull-left error"></i>
Error
</span>
<span class="message"></span>
</span>
</div>
</div> </div>
</body> </body>
</html> </html>

@ -1,4 +1,4 @@
<form class="pure-form pure-form-aligned form_createnode"> <form method="post" action="/nodes/create" class="pure-form pure-form-aligned form_createnode" data-hook-callback="callbackNodeCreated">
<div class="toolbarwindow-contents"> <div class="toolbarwindow-contents">
<div class="pure-g"> <div class="pure-g">
<div class="form-block"> <div class="form-block">
@ -8,7 +8,7 @@
<div class="formfield"> <div class="formfield">
<div class="pure-u-1-3 label"> <div class="pure-u-1-3 label">
<label for="input_createnode_name">Name</label> <label for="input_createnode_name">Name <i class="icon-exclamation-sign required"></i></label>
</div> </div>
<div class="pure-u-2-3"> <div class="pure-u-2-3">
<input class="pure-input-1" type="text" name="name" id="input_createnode_name"> <input class="pure-input-1" type="text" name="name" id="input_createnode_name">
@ -43,6 +43,6 @@
</div> </div>
</div> </div>
<div class="toolbarwindow-toolbar"> <div class="toolbarwindow-toolbar">
<button type="submit" class="pure-button okay shadow"><i class="icon-ok"></i>Create</button> <button type="submit" class="pure-button okay shadow" data-submit-icon="icon-spinner icon-spin"><i class="icon-ok"></i>Create</button>
</div> </div>
</form> </form>

Loading…
Cancel
Save