Commit ddf08198 authored by merlinofchaos's avatar merlinofchaos

A few more steps in the UI

parent f5da368b
......@@ -82,16 +82,20 @@
background-color: #eee;
}
.views-ajax-pad {
#views-ajax-pad {
border: 1px solid black;
margin-top: 10px;
min-height: 200px;
_height: 200px; /* stupid IE */
padding: 5px;
}
.views-ajax-pad .message {
#views-ajax-pad .message {
margin-top: 75px;
text-align: center;
}
#views-ajax-pad .form-buttons {
float: right;
}
/* $Id */
.ui-tabs-hide {
display: none;
}
This diff is collapsed.
<?php
// $Id$
/**
* @file ajax.inc
*
* Handles the server side AJAX interactions of Views.
*
* @defgroup ajax
* @{
*/
/**
* Simple render function to make sure output is what we want.
*/
function views_ajax_render($output = NULL, $title = NULL, $url = NULL) {
if (empty($output)) {
$output->display = t('Server reports invalid input error.');
$output->title = t('Error');
}
elseif (!is_object($output)) {
$temp = new stdClass();
$temp->display = $output;
$temp->title = $title;
$temp->url = $url;
$output = $temp;
}
drupal_set_header('Content-Type: text/javascript; charset=utf-8');
print drupal_to_js($output);
exit;
}
/**
* Handle a form for AJAX in a manner that happens to be basically the
* opposite of the normal flow; if the form hasn't been processed,
* just render it and exit; if it has been submitted successfuly, however,
* then we return whatever the submit function returned and do our
* next step accordingly.
*
* Much of this code is from drupal_get_form and/or drupal_process_form.
*
* @param $form_id
* The id of the form
* @param ...
* Any arguments that go to the form.
*/
function views_ajax_form($form_id) {
$args = func_get_args();
// Insert a placeholder for the form state so we can then assign a reference to it.
array_splice($args, 1, 0, array(NULL));
// Create the empty form state object.
$form_state = array('storage' => NULL, 'submitted' => FALSE, 'post' => $_POST, 'ajax' => TRUE);
// Replace the URL with the empty form state object as a reference:
$args[1] = &$form_state;
$form = call_user_func_array('drupal_retrieve_form', $args);
// Prepare the form. My Drupal 5 code didn't do this, so I'm not sure
// if it is necessary in D6 or not.
$form_build_id = 'form-'. md5(mt_rand());
$form['#build_id'] = $form_build_id;
drupal_prepare_form($form_id, $form, $form_state);
// Process the form our own selves so we don't get some extra batch handling
// that we don't want.
$form['#post'] = $_POST;
$form_state['values'] = array();
$form = form_builder($form_id, $form, $form_state);
// from the POST data is set and matches the current form_id.
if ((!empty($form['#post']) && (isset($form['#post']['form_id']) && ($form['#post']['form_id'] == $form_id)))) {
drupal_validate_form($form_id, $form, $form_state);
// In case of successful submit, execute the form handlers and return the
// form state so the calling function can do what it needs to do next.
if ((!empty($form_state['submitted'])) && !form_get_errors() && empty($form_state['rebuild'])) {
$form_state['redirect'] = NULL;
form_execute_handlers('submit', $form, $form_state);
return $form_state;
}
}
// If the form wasn't submitted successfully, render the form.
$output = theme('status_messages');
$output .= drupal_render_form($form_id, $form);
$title = empty($form['#title']) ? '' : $form['#title'];
$url = empty($form['#url']) ? $_GET['q'] : $form['#url'];
views_ajax_render($output, $title, $url);
}
/**
* @}
*/
\ No newline at end of file
......@@ -3,20 +3,20 @@
class views_tabset {
var $tabs = array();
var $extra = '';
var $selected = NULL;
function add($name, $title = '', $body = '') {
if (is_object($name) && is_subclass_of($name, 'views_tab')) {
$this->add_tab($name);
}
if (is_array($name)) {
elseif (is_array($name)) {
foreach ($name as $real_tab) {
$this->add($real_tab);
}
return;
}
$this->add_tab(new views_tab($name, $title, $body));
else {
$this->add_tab(new views_tab($name, $title, $body));
}
}
function add_tab($tab) {
......@@ -53,10 +53,21 @@ class views_tabset {
}
}
function set_selected($name) {
$this->selected = $name;
}
function render() {
views_add_js('tabs');
views_add_css('tabs');
return theme('views_tabset', $this->tabs, $this->extra);
if (empty($this->selected)) {
$keys = array_keys($this->tabs);
$this->selected = array_shift($keys);
}
drupal_alter('views_tabset', $this);
return theme('views_tabset', $this->tabs, $this->extra, $this->selected);
}
}
......@@ -76,14 +87,13 @@ class views_tab {
}
}
function theme_views_tabset($tabs, $extra = NULL) {
$link_output = "<div class=\"views-tabs\"><ul>\n";
function theme_views_tabset($tabs, $extra = NULL, $selected = NULL) {
$link_output = "<div class=\"views-tabs\"><ul id=\"views-tabset\">\n";
$tab_output = "<div class=\"views-tab-area\">\n";
$active_tab = 0;
foreach ($tabs as $tab) {
$link_output .= '<li' . (!$active_tab ? ' class="active"': '') . '><a href="#views-tab-' . $tab->name . '">' . $tab->title . '</a></li>' . "\n";
foreach ($tabs as $name => $tab) {
$link_output .= '<li' . ($name == $selected ? ' class="active"': '') . '><a href="#views-tab-' . $tab->name . '">' . $tab->title . '</a></li>' . "\n";
$tab_output .= '<div id="views-tab-' . $tab->name . '" class="views-tab">' . $tab->render() . "</div>\n";
$active_tab = 1;
}
$link_output .= "</ul>\n";
......
......@@ -846,8 +846,8 @@ class views_db_object {
// to fill in default values here? That seems very logical.
// Add the new display object to the view.
$this->display[] = $display;
return max(array_keys($this->display));
$this->display[$id] = $display;
return $id;
}
}
......
// $Id$
/**
* @file ajax.inc
*
* Handles AJAX submission and response in Views UI.
*/
Drupal.Views.Ajax = {};
/**
* Handles the simple process of setting the ajax form area with new data.
*/
Drupal.Views.Ajax.setForm = function(title, output) {
$(Drupal.settings.views.ajax.title).html(title);
$(Drupal.settings.views.ajax.id).html(output);
}
/**
* An ajax responder that accepts a packet of JSON data and acts appropriately.
*
* The following fields control behavior.
* - 'display': Display the associated data in the form area; bind the new
* form to 'url' if appropriate. The 'title' field may also be used.
* - 'add': This is a keyed array of HTML output to add via append. The key is
* the id to append via $(key).append(value)
* - 'replace': This is a keyed array of HTML output to add via replace. The key is
* the id to append via $(key).html(value)
*
*/
Drupal.Views.Ajax.ajaxResponse = function(data) {
if (data.debug) {
alert(data.debug);
}
// Check the 'display' for data.
if (data.display) {
Drupal.Views.Ajax.setForm(data.title, data.display);
// if a URL was supplied, bind the form to it.
if (data.url) {
var ajax_area = Drupal.settings.views.ajax.id;
var ajax_title = Drupal.settings.views.ajax.title;
// Bind a click to the button to set the value for the button.
$('input[type=submit]', ajax_area).unbind('click');
$('input[type=submit]', ajax_area).click(function() {
$('form', ajax_area).append('<input type="hidden" name="'
+ $(this).attr('name') + '" value="' + $(this).val() + '">');
});
// Bind forms to ajax submit.
$('form', ajax_area).unbind('submit'); // be safe here.
$('form', ajax_area).submit(function() {
$(this).ajaxSubmit({
url: url,
data: '',
type: 'POST',
success: Drupal.Views.Ajax.ajaxResponse,
error: function() { alert("An error occurred."); },
dataType: 'json'
});
return false;
});
}
Drupal.attachBehaviors(ajax_area);
}
else {
// If no display, reset the form.
Drupal.Views.Ajax.setForm('', Drupal.settings.views.ajax.defaultForm);
}
// Go through the 'add' array and add any new content we're instructed to add.
if (data.add) {
for (id in data.add) {
var newContent = $(id).append(data.add[id]);
Drupal.attachBehaviors(newContent);
}
}
// Go through the 'replace' array and replace any content we're instructed to.
if (data.replace) {
for (id in data.replace) {
$(id).html(data.replace[id]);
Drupal.attachBehaviors(id);
}
}
// Go through and add any requested tabs
if (data.tab) {
for (id in data.tab) {
$('#views-tabset').addTab(id, data.tab[id]['title'], 0);
$(id).html(data.tab[id]['body']);
Drupal.attachBehaviors(id);
// This is kind of annoying, but we have to actually to find where the new
// tab is.
var instance = $.ui.tabs.instances[$('#views-tabset').get(0).UI_TABS_UUID];
$('#views-tabset').clickTab(instance.$tabs.length);
}
}
}
Drupal.behaviors.ViewsAjaxLinks = function() {
// Make specified links ajaxy.
$('a.views-ajax-link:not(.views-processed)').addClass('views-processed').click(function() {
// Translate the href on the link to the ajax href. That way this degrades
// into a nice, normal link.
var url = $(this).attr('href');
url = url.replace('nojs', 'ajax');
// Turn on the hilite to indicate this is in use.
$(this).addClass('hilite');
$.ajax({
type: "GET",
url: url,
data: '',
success: Drupal.Views.Ajax.ajaxResponse,
error: function() { alert("An error occurred."); },
dataType: 'json'
});
return false;
});
$('form.views-ajax-form:not(.views-processed)').addClass('views-processed').submit(function() {
// Translate the href on the link to the ajax href. That way this degrades
// into a nice, normal link.
var url = Drupal.settings.views.forms[$(this).attr('id')];
$(this).ajaxSubmit({
url: url,
data: '',
type: 'POST',
success: Drupal.Views.Ajax.ajaxResponse,
error: function() { alert("An error occurred."); },
dataType: 'json'
});
return false;
});
}
......@@ -5,7 +5,7 @@ Drupal.Views = {};
*/
Drupal.behaviors.viewsTabs = function (context) {
$('.views-tabset:not(.views-processed)').addClass('views-processed').tabs({
$('#views-tabset:not(.views-processed)').addClass('views-processed').tabs({
selectedClass: 'active'
});
}
// $Id$
/**
* @file tabs.js
* jQuery UI Tabs (Tabs 3)
*
* This is nothing more than the pure jquery UI tabs implementation.
*/
(function($) {
......
......@@ -17,6 +17,8 @@ function views_ui_menu() {
'file' => 'includes/admin.inc',
);
$callback = $base + array('type' => MENU_CALLBACK);
$items['admin/build/views'] = $base + array(
'title' => t('Views'),
'page callback' => 'views_ui_list_views',
......@@ -34,11 +36,10 @@ function views_ui_menu() {
'page callback' => 'views_ui_add_page',
'type' => MENU_LOCAL_TASK
);
$items['admin/build/views/edit/%views_ui_cache'] = $base + array(
$items['admin/build/views/edit/%views_ui_cache'] = $callback + array(
'title' => t('Edit'),
'page callback' => 'views_ui_edit_page',
'page arguments' => array(4),
'type' => MENU_CALLBACK
);
$items['admin/build/views/import'] = $base + array(
'title' => t('Import'),
......@@ -51,19 +52,30 @@ function views_ui_menu() {
'callback arguments' => array('views_ui_admin_tools'),
'type' => MENU_LOCAL_TASK
);
$items['admin/build/views/delete'] = $base + array(
$items['admin/build/views/delete'] = $callback + array(
'title' => t('Edit view'),
'page callback' => 'drupal_get_form',
'callback arguments' => array('views_ui_admin_delete_confirm'),
'type' => MENU_CALLBACK
);
$items['admin/build/views/enable'] = $base + array(
$items['admin/build/views/enable'] = $callback + array(
'page callback' => 'views_ui_admin_enable_page',
'type' => MENU_CALLBACK
);
$items['admin/build/views/disable'] = $base + array(
$items['admin/build/views/disable'] = $callback + array(
'page callback' => 'views_ui_admin_disable_page',
'type' => MENU_CALLBACK
);
// lots of little edit form pieces.
$items['admin/build/views/details/%views_ui_cache'] = $callback + array(
'page callback' => 'views_ui_edit_details',
'page arguments' => array(4),
);
$items['admin/build/views/add-display/%views_ui_cache'] = $callback + array(
'page callback' => 'views_ui_add_display',
'page arguments' => array(4),
);
$items['admin/build/views/rearrange/%views_ui_cache'] = $callback + array(
'page callback' => 'views_ui_rearrange_section',
'page arguments' => array(4),
);
return $items;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment