From 81495f7ccafe3abbfe32eca68451b46d9dcb93b8 Mon Sep 17 00:00:00 2001 From: niphlod Date: Thu, 27 Jun 2013 00:00:00 +0200 Subject: [PATCH] nicer alignment, removed leftovers, new listwidget and passwordwidget --- applications/admin/static/js/web2py.js | 157 +++++++++++++--------- applications/examples/static/js/web2py.js | 157 +++++++++++++--------- applications/welcome/static/js/web2py.js | 157 +++++++++++++--------- gluon/sqlhtml.py | 69 ++-------- 4 files changed, 282 insertions(+), 258 deletions(-) diff --git a/applications/admin/static/js/web2py.js b/applications/admin/static/js/web2py.js index 3641a01f..7cbb2d19 100644 --- a/applications/admin/static/js/web2py.js +++ b/applications/admin/static/js/web2py.js @@ -84,9 +84,9 @@ $("input.time", target).each(function () { $(this).timeEntry(); }); - /*adds btn class to buttons*/ - $('button', target).addClass('btn'); - $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); + /*adds btn class to buttons*/ + $('button', target).addClass('btn'); + $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); /*no more inline javascript for PasswordWidget*/ $('input[type=password][data-w2p_entropy]', target).each(function () { web2py.validate_entropy($(this)); @@ -143,24 +143,24 @@ $('.hidden', target).hide(); web2py.manage_errors(target); web2py.ajax_fields(target); + web2py.show_if_handler(target); + }, + //manage errors in forms + manage_errors: function(target) { + $('.error', target).hide().slideDown('slow'); + //$('.error', target).hide().fadeIn('slow'); }, - //manage errors in forms - manage_errors: function(target) { - $('.error', target).hide().slideDown('slow'); - //$('.error', target).hide().fadeIn('slow'); - }, event_handlers: function () { /* This is called once for page * Ideally it should bound all the things that are needed */ var doc = $(document); doc.on('click', '.flash', function (e) { - console.log('das'); var t = $(this); if(t.css('top') == '0px') t.slideUp('slow'); else t.fadeOut(); - //if I want to display a clickable something - //inside flash, I should not be prevented to follow it + //if I want to display a clickable something + //inside flash, I should not be prevented to follow it //e.preventDefault(); }); doc.on('keyup', 'input.integer', function () { @@ -185,15 +185,15 @@ eval(decodeURIComponent(command)); } if(flash) { - web2py.flash(decodeURIComponent(flash)) + web2py.flash(decodeURIComponent(flash)) } }); doc.ajaxError(function (e, xhr, settings, exception) { - //personally I don't like it. - //if there's an error it it flashed and can be removed - //as any other message - //doc.off('click', '.flash') + //personally I don't like it. + //if there's an error it it flashed and can be removed + //as any other message + //doc.off('click', '.flash') switch(xhr.status) { case 500: web2py.flash(ajax_error_500); @@ -204,16 +204,16 @@ trap_form: function (action, target) { $('#' + target + ' form').each(function (i) { var form = $(this); - form.attr('data-w2p_target', target); + form.attr('data-w2p_target', target); if(!form.hasClass('no_trap')) { - //should be there by default ? - form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); + //should be there by default ? + form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.submit(function (e) { web2py.hide_flash(); web2py.ajax_page('post', action, form.serialize(), target, form); e.preventDefault(); }); - } + } }); }, trap_link: function (target) { @@ -242,27 +242,27 @@ }, //added 'success': function (data, status, xhr) { - //bummer for form submissions....the element is not there after complete - //because it gets replaced by the new response.... + //bummer for form submissions....the element is not there after complete + //because it gets replaced by the new response.... element.trigger('ajax:success', [data, status, xhr]); }, //added 'error': function (xhr, status, error) { - //bummer for form submissions....in addition to the element being not there after - //complete because it gets replaced by the new response, standard form - //handling just returns the same status code for good and bad - //form submissions (i.e. that triggered a validator error) + //bummer for form submissions....in addition to the element being not there after + //complete because it gets replaced by the new response, standard form + //handling just returns the same status code for good and bad + //form submissions (i.e. that triggered a validator error) element.trigger('ajax:error', [xhr, status, error]); }, 'complete': function (xhr, status) { element.trigger('ajax:complete', [xhr, status]); - var html = xhr.responseText; + var html = xhr.responseText; var content = xhr.getResponseHeader('web2py-component-content'); var t = $('#' + target); if(content == 'prepend') t.prepend(html); else if(content == 'append') t.append(html); else if(content != 'hide') t.html(html); - web2py.trap_form(action, target); + web2py.trap_form(action, target); web2py.trap_link(target); web2py.ajax_init('#' + target); } @@ -275,10 +275,10 @@ var jelement = $("#" + target); var element = jelement.get(0); var statement = "jQuery('#" + target + "').get(0).reload();"; - element.reload = function () { + jelement.reload = function () { // Continue if times is Infinity or // the times limit is not reached - if(this.reload_check()) { + if(element.reload_check()) { web2py.ajax_page('get', action, null, target, el); } }; // reload @@ -420,16 +420,16 @@ // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function (el) { - el.addClass('disabled'); - var method = el.prop('type') == 'submit' ? 'val' : 'html'; - // store enabled state - el.data('w2p:enable-with', el[method]); + el.addClass('disabled'); + var method = el.prop('type') == 'submit' ? 'val' : 'html'; + // store enabled state + el.data('w2p:enable-with', el[method]); /* little addition by default*/ if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { el.data('w2p_disable_with', 'Working...'); } - // set to disabled state - el[method](el.data('w2p_disable_with')); + // set to disabled state + el[method](el.data('w2p_disable_with')); el.bind('click.w2pDisable', function (e) { // prevent further clicking return web2py.stopEverything(e); @@ -438,29 +438,52 @@ // restore element to its original state which was disabled by 'disableElement' above enableElement: function (el) { - var method = el.prop('type') == 'submit' ? 'val' : 'html'; + var method = el.prop('type') == 'submit' ? 'val' : 'html'; if(el.data('w2p:enable-with') !== undefined) { - // set to old enabled state - el[method](el.data('w2p:enable-with')); + // set to old enabled state + el[method](el.data('w2p:enable-with')); el.removeData('w2p:enable-with'); // clean up cache } - el.removeClass('disabled'); + el.removeClass('disabled'); el.unbind('click.w2pDisable'); // enable element }, //convenience wrapper, internal use only simple_component: function (action, target, element) { web2py.component(action, target, 0, 1, element); }, - //helper for flash messages - flash: function(message, status) { - var flash = $('.flash'); - web2py.hide_flash(); - flash.html(message).addClass(status); - if(flash.html()) flash.append(' × ').slideDown(); - }, - hide_flash: function() { - $('.flash').hide().html(''); - }, + //helper for flash messages + flash: function(message, status) { + var flash = $('.flash'); + web2py.hide_flash(); + flash.html(message).addClass(status); + if(flash.html()) flash.append(' × ').slideDown(); + }, + hide_flash: function() { + $('.flash').hide().html(''); + }, + show_if_handler: function(target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for(var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if(t.is(dep.attr('data-show-if'))) tr.slideDown(); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + if(!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + }); + for(var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + }; + }, a_handler: function (el, e) { e.preventDefault(); var method = el.data('w2p_method'); @@ -535,7 +558,7 @@ web2py.enableElement($(this)); }); }, - /* Disables form elements: + /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true @@ -543,10 +566,10 @@ disableFormElements: function(form) { form.find(web2py.disableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; - var disable_with = element.data('w2p_disable_with'); - if (disable_with == undefined) { - element.data('w2p_disable_with', element[method]()) - } + var disable_with = element.data('w2p_disable_with'); + if (disable_with == undefined) { + element.data('w2p_disable_with', element[method]()) + } element.data('w2p:enable-with', element[method]()); element[method](element.data('w2p_disable_with')); element.prop('disabled', true); @@ -554,8 +577,8 @@ }, /* Re-enables disabled form elements: - - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - - Sets disabled property to false + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) + - Sets disabled property to false */ enableFormElements: function(form) { form.find(web2py.enableSelector).each(function() { @@ -564,15 +587,15 @@ element.prop('disabled', false); }); }, - form_handlers: function() { - var el = $(document); - el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { - web2py.disableFormElements($(this)); - }); - el.on('ajax:complete', 'form[data-w2p_target]', function (e) { - web2py.enableFormElements($(this)); - }); - } + form_handlers: function() { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function (e) { + web2py.enableFormElements($(this)); + }); + } } //end of functions @@ -584,7 +607,7 @@ web2py.ajax_init(document); web2py.event_handlers(); web2py.a_handlers(); - web2py.form_handlers(); + web2py.form_handlers(); }); })(jQuery); diff --git a/applications/examples/static/js/web2py.js b/applications/examples/static/js/web2py.js index 3641a01f..7cbb2d19 100644 --- a/applications/examples/static/js/web2py.js +++ b/applications/examples/static/js/web2py.js @@ -84,9 +84,9 @@ $("input.time", target).each(function () { $(this).timeEntry(); }); - /*adds btn class to buttons*/ - $('button', target).addClass('btn'); - $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); + /*adds btn class to buttons*/ + $('button', target).addClass('btn'); + $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); /*no more inline javascript for PasswordWidget*/ $('input[type=password][data-w2p_entropy]', target).each(function () { web2py.validate_entropy($(this)); @@ -143,24 +143,24 @@ $('.hidden', target).hide(); web2py.manage_errors(target); web2py.ajax_fields(target); + web2py.show_if_handler(target); + }, + //manage errors in forms + manage_errors: function(target) { + $('.error', target).hide().slideDown('slow'); + //$('.error', target).hide().fadeIn('slow'); }, - //manage errors in forms - manage_errors: function(target) { - $('.error', target).hide().slideDown('slow'); - //$('.error', target).hide().fadeIn('slow'); - }, event_handlers: function () { /* This is called once for page * Ideally it should bound all the things that are needed */ var doc = $(document); doc.on('click', '.flash', function (e) { - console.log('das'); var t = $(this); if(t.css('top') == '0px') t.slideUp('slow'); else t.fadeOut(); - //if I want to display a clickable something - //inside flash, I should not be prevented to follow it + //if I want to display a clickable something + //inside flash, I should not be prevented to follow it //e.preventDefault(); }); doc.on('keyup', 'input.integer', function () { @@ -185,15 +185,15 @@ eval(decodeURIComponent(command)); } if(flash) { - web2py.flash(decodeURIComponent(flash)) + web2py.flash(decodeURIComponent(flash)) } }); doc.ajaxError(function (e, xhr, settings, exception) { - //personally I don't like it. - //if there's an error it it flashed and can be removed - //as any other message - //doc.off('click', '.flash') + //personally I don't like it. + //if there's an error it it flashed and can be removed + //as any other message + //doc.off('click', '.flash') switch(xhr.status) { case 500: web2py.flash(ajax_error_500); @@ -204,16 +204,16 @@ trap_form: function (action, target) { $('#' + target + ' form').each(function (i) { var form = $(this); - form.attr('data-w2p_target', target); + form.attr('data-w2p_target', target); if(!form.hasClass('no_trap')) { - //should be there by default ? - form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); + //should be there by default ? + form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.submit(function (e) { web2py.hide_flash(); web2py.ajax_page('post', action, form.serialize(), target, form); e.preventDefault(); }); - } + } }); }, trap_link: function (target) { @@ -242,27 +242,27 @@ }, //added 'success': function (data, status, xhr) { - //bummer for form submissions....the element is not there after complete - //because it gets replaced by the new response.... + //bummer for form submissions....the element is not there after complete + //because it gets replaced by the new response.... element.trigger('ajax:success', [data, status, xhr]); }, //added 'error': function (xhr, status, error) { - //bummer for form submissions....in addition to the element being not there after - //complete because it gets replaced by the new response, standard form - //handling just returns the same status code for good and bad - //form submissions (i.e. that triggered a validator error) + //bummer for form submissions....in addition to the element being not there after + //complete because it gets replaced by the new response, standard form + //handling just returns the same status code for good and bad + //form submissions (i.e. that triggered a validator error) element.trigger('ajax:error', [xhr, status, error]); }, 'complete': function (xhr, status) { element.trigger('ajax:complete', [xhr, status]); - var html = xhr.responseText; + var html = xhr.responseText; var content = xhr.getResponseHeader('web2py-component-content'); var t = $('#' + target); if(content == 'prepend') t.prepend(html); else if(content == 'append') t.append(html); else if(content != 'hide') t.html(html); - web2py.trap_form(action, target); + web2py.trap_form(action, target); web2py.trap_link(target); web2py.ajax_init('#' + target); } @@ -275,10 +275,10 @@ var jelement = $("#" + target); var element = jelement.get(0); var statement = "jQuery('#" + target + "').get(0).reload();"; - element.reload = function () { + jelement.reload = function () { // Continue if times is Infinity or // the times limit is not reached - if(this.reload_check()) { + if(element.reload_check()) { web2py.ajax_page('get', action, null, target, el); } }; // reload @@ -420,16 +420,16 @@ // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function (el) { - el.addClass('disabled'); - var method = el.prop('type') == 'submit' ? 'val' : 'html'; - // store enabled state - el.data('w2p:enable-with', el[method]); + el.addClass('disabled'); + var method = el.prop('type') == 'submit' ? 'val' : 'html'; + // store enabled state + el.data('w2p:enable-with', el[method]); /* little addition by default*/ if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { el.data('w2p_disable_with', 'Working...'); } - // set to disabled state - el[method](el.data('w2p_disable_with')); + // set to disabled state + el[method](el.data('w2p_disable_with')); el.bind('click.w2pDisable', function (e) { // prevent further clicking return web2py.stopEverything(e); @@ -438,29 +438,52 @@ // restore element to its original state which was disabled by 'disableElement' above enableElement: function (el) { - var method = el.prop('type') == 'submit' ? 'val' : 'html'; + var method = el.prop('type') == 'submit' ? 'val' : 'html'; if(el.data('w2p:enable-with') !== undefined) { - // set to old enabled state - el[method](el.data('w2p:enable-with')); + // set to old enabled state + el[method](el.data('w2p:enable-with')); el.removeData('w2p:enable-with'); // clean up cache } - el.removeClass('disabled'); + el.removeClass('disabled'); el.unbind('click.w2pDisable'); // enable element }, //convenience wrapper, internal use only simple_component: function (action, target, element) { web2py.component(action, target, 0, 1, element); }, - //helper for flash messages - flash: function(message, status) { - var flash = $('.flash'); - web2py.hide_flash(); - flash.html(message).addClass(status); - if(flash.html()) flash.append(' × ').slideDown(); - }, - hide_flash: function() { - $('.flash').hide().html(''); - }, + //helper for flash messages + flash: function(message, status) { + var flash = $('.flash'); + web2py.hide_flash(); + flash.html(message).addClass(status); + if(flash.html()) flash.append(' × ').slideDown(); + }, + hide_flash: function() { + $('.flash').hide().html(''); + }, + show_if_handler: function(target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for(var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if(t.is(dep.attr('data-show-if'))) tr.slideDown(); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + if(!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + }); + for(var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + }; + }, a_handler: function (el, e) { e.preventDefault(); var method = el.data('w2p_method'); @@ -535,7 +558,7 @@ web2py.enableElement($(this)); }); }, - /* Disables form elements: + /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true @@ -543,10 +566,10 @@ disableFormElements: function(form) { form.find(web2py.disableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; - var disable_with = element.data('w2p_disable_with'); - if (disable_with == undefined) { - element.data('w2p_disable_with', element[method]()) - } + var disable_with = element.data('w2p_disable_with'); + if (disable_with == undefined) { + element.data('w2p_disable_with', element[method]()) + } element.data('w2p:enable-with', element[method]()); element[method](element.data('w2p_disable_with')); element.prop('disabled', true); @@ -554,8 +577,8 @@ }, /* Re-enables disabled form elements: - - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - - Sets disabled property to false + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) + - Sets disabled property to false */ enableFormElements: function(form) { form.find(web2py.enableSelector).each(function() { @@ -564,15 +587,15 @@ element.prop('disabled', false); }); }, - form_handlers: function() { - var el = $(document); - el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { - web2py.disableFormElements($(this)); - }); - el.on('ajax:complete', 'form[data-w2p_target]', function (e) { - web2py.enableFormElements($(this)); - }); - } + form_handlers: function() { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function (e) { + web2py.enableFormElements($(this)); + }); + } } //end of functions @@ -584,7 +607,7 @@ web2py.ajax_init(document); web2py.event_handlers(); web2py.a_handlers(); - web2py.form_handlers(); + web2py.form_handlers(); }); })(jQuery); diff --git a/applications/welcome/static/js/web2py.js b/applications/welcome/static/js/web2py.js index 3641a01f..7cbb2d19 100644 --- a/applications/welcome/static/js/web2py.js +++ b/applications/welcome/static/js/web2py.js @@ -84,9 +84,9 @@ $("input.time", target).each(function () { $(this).timeEntry(); }); - /*adds btn class to buttons*/ - $('button', target).addClass('btn'); - $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); + /*adds btn class to buttons*/ + $('button', target).addClass('btn'); + $('form input[type="submit"], form input[type="button"]', target).addClass('btn'); /*no more inline javascript for PasswordWidget*/ $('input[type=password][data-w2p_entropy]', target).each(function () { web2py.validate_entropy($(this)); @@ -143,24 +143,24 @@ $('.hidden', target).hide(); web2py.manage_errors(target); web2py.ajax_fields(target); + web2py.show_if_handler(target); + }, + //manage errors in forms + manage_errors: function(target) { + $('.error', target).hide().slideDown('slow'); + //$('.error', target).hide().fadeIn('slow'); }, - //manage errors in forms - manage_errors: function(target) { - $('.error', target).hide().slideDown('slow'); - //$('.error', target).hide().fadeIn('slow'); - }, event_handlers: function () { /* This is called once for page * Ideally it should bound all the things that are needed */ var doc = $(document); doc.on('click', '.flash', function (e) { - console.log('das'); var t = $(this); if(t.css('top') == '0px') t.slideUp('slow'); else t.fadeOut(); - //if I want to display a clickable something - //inside flash, I should not be prevented to follow it + //if I want to display a clickable something + //inside flash, I should not be prevented to follow it //e.preventDefault(); }); doc.on('keyup', 'input.integer', function () { @@ -185,15 +185,15 @@ eval(decodeURIComponent(command)); } if(flash) { - web2py.flash(decodeURIComponent(flash)) + web2py.flash(decodeURIComponent(flash)) } }); doc.ajaxError(function (e, xhr, settings, exception) { - //personally I don't like it. - //if there's an error it it flashed and can be removed - //as any other message - //doc.off('click', '.flash') + //personally I don't like it. + //if there's an error it it flashed and can be removed + //as any other message + //doc.off('click', '.flash') switch(xhr.status) { case 500: web2py.flash(ajax_error_500); @@ -204,16 +204,16 @@ trap_form: function (action, target) { $('#' + target + ' form').each(function (i) { var form = $(this); - form.attr('data-w2p_target', target); + form.attr('data-w2p_target', target); if(!form.hasClass('no_trap')) { - //should be there by default ? - form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); + //should be there by default ? + form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.submit(function (e) { web2py.hide_flash(); web2py.ajax_page('post', action, form.serialize(), target, form); e.preventDefault(); }); - } + } }); }, trap_link: function (target) { @@ -242,27 +242,27 @@ }, //added 'success': function (data, status, xhr) { - //bummer for form submissions....the element is not there after complete - //because it gets replaced by the new response.... + //bummer for form submissions....the element is not there after complete + //because it gets replaced by the new response.... element.trigger('ajax:success', [data, status, xhr]); }, //added 'error': function (xhr, status, error) { - //bummer for form submissions....in addition to the element being not there after - //complete because it gets replaced by the new response, standard form - //handling just returns the same status code for good and bad - //form submissions (i.e. that triggered a validator error) + //bummer for form submissions....in addition to the element being not there after + //complete because it gets replaced by the new response, standard form + //handling just returns the same status code for good and bad + //form submissions (i.e. that triggered a validator error) element.trigger('ajax:error', [xhr, status, error]); }, 'complete': function (xhr, status) { element.trigger('ajax:complete', [xhr, status]); - var html = xhr.responseText; + var html = xhr.responseText; var content = xhr.getResponseHeader('web2py-component-content'); var t = $('#' + target); if(content == 'prepend') t.prepend(html); else if(content == 'append') t.append(html); else if(content != 'hide') t.html(html); - web2py.trap_form(action, target); + web2py.trap_form(action, target); web2py.trap_link(target); web2py.ajax_init('#' + target); } @@ -275,10 +275,10 @@ var jelement = $("#" + target); var element = jelement.get(0); var statement = "jQuery('#" + target + "').get(0).reload();"; - element.reload = function () { + jelement.reload = function () { // Continue if times is Infinity or // the times limit is not reached - if(this.reload_check()) { + if(element.reload_check()) { web2py.ajax_page('get', action, null, target, el); } }; // reload @@ -420,16 +420,16 @@ // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function (el) { - el.addClass('disabled'); - var method = el.prop('type') == 'submit' ? 'val' : 'html'; - // store enabled state - el.data('w2p:enable-with', el[method]); + el.addClass('disabled'); + var method = el.prop('type') == 'submit' ? 'val' : 'html'; + // store enabled state + el.data('w2p:enable-with', el[method]); /* little addition by default*/ if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { el.data('w2p_disable_with', 'Working...'); } - // set to disabled state - el[method](el.data('w2p_disable_with')); + // set to disabled state + el[method](el.data('w2p_disable_with')); el.bind('click.w2pDisable', function (e) { // prevent further clicking return web2py.stopEverything(e); @@ -438,29 +438,52 @@ // restore element to its original state which was disabled by 'disableElement' above enableElement: function (el) { - var method = el.prop('type') == 'submit' ? 'val' : 'html'; + var method = el.prop('type') == 'submit' ? 'val' : 'html'; if(el.data('w2p:enable-with') !== undefined) { - // set to old enabled state - el[method](el.data('w2p:enable-with')); + // set to old enabled state + el[method](el.data('w2p:enable-with')); el.removeData('w2p:enable-with'); // clean up cache } - el.removeClass('disabled'); + el.removeClass('disabled'); el.unbind('click.w2pDisable'); // enable element }, //convenience wrapper, internal use only simple_component: function (action, target, element) { web2py.component(action, target, 0, 1, element); }, - //helper for flash messages - flash: function(message, status) { - var flash = $('.flash'); - web2py.hide_flash(); - flash.html(message).addClass(status); - if(flash.html()) flash.append(' × ').slideDown(); - }, - hide_flash: function() { - $('.flash').hide().html(''); - }, + //helper for flash messages + flash: function(message, status) { + var flash = $('.flash'); + web2py.hide_flash(); + flash.html(message).addClass(status); + if(flash.html()) flash.append(' × ').slideDown(); + }, + hide_flash: function() { + $('.flash').hide().html(''); + }, + show_if_handler: function(target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for(var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if(t.is(dep.attr('data-show-if'))) tr.slideDown(); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + if(!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + }); + for(var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + }; + }, a_handler: function (el, e) { e.preventDefault(); var method = el.data('w2p_method'); @@ -535,7 +558,7 @@ web2py.enableElement($(this)); }); }, - /* Disables form elements: + /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true @@ -543,10 +566,10 @@ disableFormElements: function(form) { form.find(web2py.disableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; - var disable_with = element.data('w2p_disable_with'); - if (disable_with == undefined) { - element.data('w2p_disable_with', element[method]()) - } + var disable_with = element.data('w2p_disable_with'); + if (disable_with == undefined) { + element.data('w2p_disable_with', element[method]()) + } element.data('w2p:enable-with', element[method]()); element[method](element.data('w2p_disable_with')); element.prop('disabled', true); @@ -554,8 +577,8 @@ }, /* Re-enables disabled form elements: - - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - - Sets disabled property to false + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) + - Sets disabled property to false */ enableFormElements: function(form) { form.find(web2py.enableSelector).each(function() { @@ -564,15 +587,15 @@ element.prop('disabled', false); }); }, - form_handlers: function() { - var el = $(document); - el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { - web2py.disableFormElements($(this)); - }); - el.on('ajax:complete', 'form[data-w2p_target]', function (e) { - web2py.enableFormElements($(this)); - }); - } + form_handlers: function() { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function (e) { + web2py.enableFormElements($(this)); + }); + } } //end of functions @@ -584,7 +607,7 @@ web2py.ajax_init(document); web2py.event_handlers(); web2py.a_handlers(); - web2py.form_handlers(); + web2py.form_handlers(); }); })(jQuery); diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index 2f99adc5..26720803 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -86,8 +86,8 @@ def show_if(cond): if not cond: return None base = "%s_%s" % (cond.first.tablename, cond.first.name) - if ((cond.op.__name__ == 'EQ' and cond.second == True) or - (cond.op.__name__ == 'NE' and cond.second == False)): + if ((cond.op.__name__ == 'EQ' and cond.second == True) or + (cond.op.__name__ == 'NE' and cond.second == False)): return base,":checked" if ((cond.op.__name__ == 'EQ' and cond.second == False) or (cond.op.__name__ == 'NE' and cond.second == True)): @@ -97,7 +97,7 @@ def show_if(cond): if cond.op.__name__ == 'NE': return base,"[value!='%s']" % cond.second if cond.op.__name__ == 'CONTAINS': - return base,"[value~='%s']" % cond.second + return base,"[value~='%s']" % cond.second if cond.op.__name__ == 'BELONGS' and isinstance(cond.second,(list,tuple)): return base,','.join("[value='%s']" % (v) for v in cond.second) raise RuntimeError("Not Implemented Error") @@ -126,7 +126,7 @@ class FormWidget(object): _id='%s_%s' % (field.tablename, field.name), _class=cls._class or widget_class.match(str(field.type)).group(), - _name=field.name, + _name=field.name, requires=field.requires, ) if getattr(field,'show_if',None): @@ -295,57 +295,15 @@ class ListWidget(StringWidget): _class = 'string' requires = field.requires if isinstance( field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None - attributes['_style'] = 'list-style:none' nvalue = value or [''] items = [LI(INPUT(_id=_id, _class=_class, _name=_name, value=v, hideerror=k < len(nvalue) - 1, requires=requires), **attributes) for (k, v) in enumerate(nvalue)] - script = SCRIPT(""" -// from http://refactormycode.com/codes/694-expanding-input-list-using-jquery -(function(){ -jQuery.fn.grow_input = function() { - return this.each(function() { - var ul = this; - jQuery(ul).find(":text").after('+ -').keypress(function (e) { return (e.which == 13) ? pe(ul, e) : true; }).next().click(function(e){ pe(ul, e) }).next().click(function(e){ rl(ul, e)}); - }); -}; -function pe(ul, e) { - var new_line = ml(ul); - rel(ul); - if (jQuery(e.target).parent().is(':visible')) { - //make sure we didn't delete the element before we insert after - new_line.insertAfter(jQuery(e.target).parent()); - } else { - //the line we clicked on was deleted, just add to end of list - new_line.appendTo(ul); - } - new_line.find(":text").focus(); - return false; -} -function rl(ul, e) { - if (jQuery(ul).children().length > 1) { - //only remove if we have more than 1 item so the list is never empty - jQuery(e.target).parent().remove(); - } -} -function ml(ul) { - var line = jQuery(ul).find("li:first").clone(true); - line.find(':text').val(''); - return line; -} -function rel(ul) { - jQuery(ul).find("li").each(function() { - var trimmed = jQuery.trim(jQuery(this.firstChild).val()); - if (trimmed=='') jQuery(this).remove(); else jQuery(this.firstChild).val(trimmed); - }); -} -})(); -jQuery(document).ready(function(){jQuery('#%s_grow_input').grow_input();}); -""" % _id) attributes['_id'] = _id + '_grow_input' attributes['_style'] = 'list-style:none' - return TAG[''](UL(*items, **attributes), script) + attributes['_class'] = 'w2p_list' + return TAG[''](UL(*items, **attributes)) class MultipleOptionsWidget(OptionsWidget): @@ -521,7 +479,6 @@ class PasswordWidget(FormWidget): _value=(value and cls.DEFAULT_PASSWORD_DISPLAY) or '', ) attr = cls._attributes(field, default, **attributes) - output = CAT(INPUT(**attr)) # deal with entropy check! requires = field.requires @@ -529,10 +486,9 @@ class PasswordWidget(FormWidget): requires = [requires] is_strong = [r for r in requires if isinstance(r, IS_STRONG)] if is_strong: - output.append(SCRIPT("web2py_validate_entropy(jQuery('#%s'),%s);" % ( - attr['_id'], is_strong[0].entropy - if is_strong[0].entropy else "null"))) + attr['_data-w2p_entropy'] = is_strong[0].entropy if is_strong[0].entropy else "null" # end entropy check + output = INPUT(**attr) return output @@ -651,7 +607,7 @@ class AutocompleteWidget(object): self.help_fields = help_fields or [] self.help_string = help_string if self.help_fields and not self.help_string: - self.help_string = ' '.join('%%(%s)s'%f.name + self.help_string = ' '.join('%%(%s)s'%f.name for f in self.help_fields) self.request = request @@ -1484,7 +1440,7 @@ class SQLFORM(FORM): continue else: f = os.path.join( - current.request.folder, + current.request.folder, os.path.normpath(f)) source_file = open(f, 'rb') original_filename = os.path.split(f)[1] @@ -2141,7 +2097,7 @@ class SQLFORM(FORM): else: rows = dbset.select(left=left, orderby=orderby, cacheable=True, *expcolumns) - + value = exportManager[export_type] clazz = value[0] if hasattr(value, '__getitem__') else value oExp = clazz(rows) @@ -2694,7 +2650,7 @@ class SQLFORM(FORM): elif grid.view_form: header = T('View %(entity)s') % dict( entity=format(grid.view_form.table, - grid.view_form.record)) + grid.view_form.record)) if next: breadcrumbs.append(LI( A(T(header), _class=trap_class(),_href=url()), @@ -3136,4 +3092,3 @@ class ExporterJSON(ExportClass): return self.rows.as_json() else: return 'null' -