Merge pull request #115 from niphlod/feature/js_inline

nicer alignment, removed leftovers, new listwidget and passwordwidget
This commit is contained in:
mdipierro
2013-06-26 23:01:05 -07:00
4 changed files with 282 additions and 258 deletions
+90 -67
View File
@@ -84,9 +84,9 @@
$("input.time", target).each(function () { $("input.time", target).each(function () {
$(this).timeEntry(); $(this).timeEntry();
}); });
/*adds btn class to buttons*/ /*adds btn class to buttons*/
$('button', target).addClass('btn'); $('button', target).addClass('btn');
$('form input[type="submit"], form input[type="button"]', target).addClass('btn'); $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
/*no more inline javascript for PasswordWidget*/ /*no more inline javascript for PasswordWidget*/
$('input[type=password][data-w2p_entropy]', target).each(function () { $('input[type=password][data-w2p_entropy]', target).each(function () {
web2py.validate_entropy($(this)); web2py.validate_entropy($(this));
@@ -143,24 +143,24 @@
$('.hidden', target).hide(); $('.hidden', target).hide();
web2py.manage_errors(target); web2py.manage_errors(target);
web2py.ajax_fields(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 () { event_handlers: function () {
/* This is called once for page /* This is called once for page
* Ideally it should bound all the things that are needed * Ideally it should bound all the things that are needed
*/ */
var doc = $(document); var doc = $(document);
doc.on('click', '.flash', function (e) { doc.on('click', '.flash', function (e) {
console.log('das');
var t = $(this); var t = $(this);
if(t.css('top') == '0px') t.slideUp('slow'); if(t.css('top') == '0px') t.slideUp('slow');
else t.fadeOut(); else t.fadeOut();
//if I want to display a clickable something //if I want to display a clickable something
//inside flash, I should not be prevented to follow it //inside flash, I should not be prevented to follow it
//e.preventDefault(); //e.preventDefault();
}); });
doc.on('keyup', 'input.integer', function () { doc.on('keyup', 'input.integer', function () {
@@ -185,15 +185,15 @@
eval(decodeURIComponent(command)); eval(decodeURIComponent(command));
} }
if(flash) { if(flash) {
web2py.flash(decodeURIComponent(flash)) web2py.flash(decodeURIComponent(flash))
} }
}); });
doc.ajaxError(function (e, xhr, settings, exception) { doc.ajaxError(function (e, xhr, settings, exception) {
//personally I don't like it. //personally I don't like it.
//if there's an error it it flashed and can be removed //if there's an error it it flashed and can be removed
//as any other message //as any other message
//doc.off('click', '.flash') //doc.off('click', '.flash')
switch(xhr.status) { switch(xhr.status) {
case 500: case 500:
web2py.flash(ajax_error_500); web2py.flash(ajax_error_500);
@@ -204,16 +204,16 @@
trap_form: function (action, target) { trap_form: function (action, target) {
$('#' + target + ' form').each(function (i) { $('#' + target + ' form').each(function (i) {
var form = $(this); var form = $(this);
form.attr('data-w2p_target', target); form.attr('data-w2p_target', target);
if(!form.hasClass('no_trap')) { if(!form.hasClass('no_trap')) {
//should be there by default ? //should be there by default ?
form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...');
form.submit(function (e) { form.submit(function (e) {
web2py.hide_flash(); web2py.hide_flash();
web2py.ajax_page('post', action, form.serialize(), target, form); web2py.ajax_page('post', action, form.serialize(), target, form);
e.preventDefault(); e.preventDefault();
}); });
} }
}); });
}, },
trap_link: function (target) { trap_link: function (target) {
@@ -242,27 +242,27 @@
}, },
//added //added
'success': function (data, status, xhr) { 'success': function (data, status, xhr) {
//bummer for form submissions....the element is not there after complete //bummer for form submissions....the element is not there after complete
//because it gets replaced by the new response.... //because it gets replaced by the new response....
element.trigger('ajax:success', [data, status, xhr]); element.trigger('ajax:success', [data, status, xhr]);
}, },
//added //added
'error': function (xhr, status, error) { 'error': function (xhr, status, error) {
//bummer for form submissions....in addition to the element being not there after //bummer for form submissions....in addition to the element being not there after
//complete because it gets replaced by the new response, standard form //complete because it gets replaced by the new response, standard form
//handling just returns the same status code for good and bad //handling just returns the same status code for good and bad
//form submissions (i.e. that triggered a validator error) //form submissions (i.e. that triggered a validator error)
element.trigger('ajax:error', [xhr, status, error]); element.trigger('ajax:error', [xhr, status, error]);
}, },
'complete': function (xhr, status) { 'complete': function (xhr, status) {
element.trigger('ajax:complete', [xhr, status]); element.trigger('ajax:complete', [xhr, status]);
var html = xhr.responseText; var html = xhr.responseText;
var content = xhr.getResponseHeader('web2py-component-content'); var content = xhr.getResponseHeader('web2py-component-content');
var t = $('#' + target); var t = $('#' + target);
if(content == 'prepend') t.prepend(html); if(content == 'prepend') t.prepend(html);
else if(content == 'append') t.append(html); else if(content == 'append') t.append(html);
else if(content != 'hide') t.html(html); else if(content != 'hide') t.html(html);
web2py.trap_form(action, target); web2py.trap_form(action, target);
web2py.trap_link(target); web2py.trap_link(target);
web2py.ajax_init('#' + target); web2py.ajax_init('#' + target);
} }
@@ -275,10 +275,10 @@
var jelement = $("#" + target); var jelement = $("#" + target);
var element = jelement.get(0); var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();"; var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function () { jelement.reload = function () {
// Continue if times is Infinity or // Continue if times is Infinity or
// the times limit is not reached // the times limit is not reached
if(this.reload_check()) { if(element.reload_check()) {
web2py.ajax_page('get', action, null, target, el); web2py.ajax_page('get', action, null, target, el);
} }
}; // reload }; // reload
@@ -420,16 +420,16 @@
// replace element's html with the 'data-disable-with' after storing original html // replace element's html with the 'data-disable-with' after storing original html
// and prevent clicking on it // and prevent clicking on it
disableElement: function (el) { disableElement: function (el) {
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]);
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
} }
// set to disabled state // set to disabled state
el[method](el.data('w2p_disable_with')); el[method](el.data('w2p_disable_with'));
el.bind('click.w2pDisable', function (e) { // prevent further clicking el.bind('click.w2pDisable', function (e) { // prevent further clicking
return web2py.stopEverything(e); return web2py.stopEverything(e);
@@ -438,29 +438,52 @@
// restore element to its original state which was disabled by 'disableElement' above // restore element to its original state which was disabled by 'disableElement' above
enableElement: function (el) { 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) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
el.removeClass('disabled'); el.removeClass('disabled');
el.unbind('click.w2pDisable'); // enable element el.unbind('click.w2pDisable'); // enable element
}, },
//convenience wrapper, internal use only //convenience wrapper, internal use only
simple_component: function (action, target, element) { simple_component: function (action, target, element) {
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function(message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function() {
$('.flash').hide().html(''); $('.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) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
var method = el.data('w2p_method'); var method = el.data('w2p_method');
@@ -535,7 +558,7 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
@@ -543,10 +566,10 @@
disableFormElements: function(form) { disableFormElements: function(form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function() {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this), method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if (disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
element[method](element.data('w2p_disable_with')); element[method](element.data('w2p_disable_with'));
element.prop('disabled', true); element.prop('disabled', true);
@@ -554,8 +577,8 @@
}, },
/* Re-enables disabled form elements: /* Re-enables disabled form elements:
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function(form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function() {
@@ -564,15 +587,15 @@
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function() {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
}); });
el.on('ajax:complete', 'form[data-w2p_target]', function (e) { el.on('ajax:complete', 'form[data-w2p_target]', function (e) {
web2py.enableFormElements($(this)); web2py.enableFormElements($(this));
}); });
} }
} }
//end of functions //end of functions
@@ -584,7 +607,7 @@
web2py.ajax_init(document); web2py.ajax_init(document);
web2py.event_handlers(); web2py.event_handlers();
web2py.a_handlers(); web2py.a_handlers();
web2py.form_handlers(); web2py.form_handlers();
}); });
})(jQuery); })(jQuery);
+90 -67
View File
@@ -84,9 +84,9 @@
$("input.time", target).each(function () { $("input.time", target).each(function () {
$(this).timeEntry(); $(this).timeEntry();
}); });
/*adds btn class to buttons*/ /*adds btn class to buttons*/
$('button', target).addClass('btn'); $('button', target).addClass('btn');
$('form input[type="submit"], form input[type="button"]', target).addClass('btn'); $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
/*no more inline javascript for PasswordWidget*/ /*no more inline javascript for PasswordWidget*/
$('input[type=password][data-w2p_entropy]', target).each(function () { $('input[type=password][data-w2p_entropy]', target).each(function () {
web2py.validate_entropy($(this)); web2py.validate_entropy($(this));
@@ -143,24 +143,24 @@
$('.hidden', target).hide(); $('.hidden', target).hide();
web2py.manage_errors(target); web2py.manage_errors(target);
web2py.ajax_fields(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 () { event_handlers: function () {
/* This is called once for page /* This is called once for page
* Ideally it should bound all the things that are needed * Ideally it should bound all the things that are needed
*/ */
var doc = $(document); var doc = $(document);
doc.on('click', '.flash', function (e) { doc.on('click', '.flash', function (e) {
console.log('das');
var t = $(this); var t = $(this);
if(t.css('top') == '0px') t.slideUp('slow'); if(t.css('top') == '0px') t.slideUp('slow');
else t.fadeOut(); else t.fadeOut();
//if I want to display a clickable something //if I want to display a clickable something
//inside flash, I should not be prevented to follow it //inside flash, I should not be prevented to follow it
//e.preventDefault(); //e.preventDefault();
}); });
doc.on('keyup', 'input.integer', function () { doc.on('keyup', 'input.integer', function () {
@@ -185,15 +185,15 @@
eval(decodeURIComponent(command)); eval(decodeURIComponent(command));
} }
if(flash) { if(flash) {
web2py.flash(decodeURIComponent(flash)) web2py.flash(decodeURIComponent(flash))
} }
}); });
doc.ajaxError(function (e, xhr, settings, exception) { doc.ajaxError(function (e, xhr, settings, exception) {
//personally I don't like it. //personally I don't like it.
//if there's an error it it flashed and can be removed //if there's an error it it flashed and can be removed
//as any other message //as any other message
//doc.off('click', '.flash') //doc.off('click', '.flash')
switch(xhr.status) { switch(xhr.status) {
case 500: case 500:
web2py.flash(ajax_error_500); web2py.flash(ajax_error_500);
@@ -204,16 +204,16 @@
trap_form: function (action, target) { trap_form: function (action, target) {
$('#' + target + ' form').each(function (i) { $('#' + target + ' form').each(function (i) {
var form = $(this); var form = $(this);
form.attr('data-w2p_target', target); form.attr('data-w2p_target', target);
if(!form.hasClass('no_trap')) { if(!form.hasClass('no_trap')) {
//should be there by default ? //should be there by default ?
form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...');
form.submit(function (e) { form.submit(function (e) {
web2py.hide_flash(); web2py.hide_flash();
web2py.ajax_page('post', action, form.serialize(), target, form); web2py.ajax_page('post', action, form.serialize(), target, form);
e.preventDefault(); e.preventDefault();
}); });
} }
}); });
}, },
trap_link: function (target) { trap_link: function (target) {
@@ -242,27 +242,27 @@
}, },
//added //added
'success': function (data, status, xhr) { 'success': function (data, status, xhr) {
//bummer for form submissions....the element is not there after complete //bummer for form submissions....the element is not there after complete
//because it gets replaced by the new response.... //because it gets replaced by the new response....
element.trigger('ajax:success', [data, status, xhr]); element.trigger('ajax:success', [data, status, xhr]);
}, },
//added //added
'error': function (xhr, status, error) { 'error': function (xhr, status, error) {
//bummer for form submissions....in addition to the element being not there after //bummer for form submissions....in addition to the element being not there after
//complete because it gets replaced by the new response, standard form //complete because it gets replaced by the new response, standard form
//handling just returns the same status code for good and bad //handling just returns the same status code for good and bad
//form submissions (i.e. that triggered a validator error) //form submissions (i.e. that triggered a validator error)
element.trigger('ajax:error', [xhr, status, error]); element.trigger('ajax:error', [xhr, status, error]);
}, },
'complete': function (xhr, status) { 'complete': function (xhr, status) {
element.trigger('ajax:complete', [xhr, status]); element.trigger('ajax:complete', [xhr, status]);
var html = xhr.responseText; var html = xhr.responseText;
var content = xhr.getResponseHeader('web2py-component-content'); var content = xhr.getResponseHeader('web2py-component-content');
var t = $('#' + target); var t = $('#' + target);
if(content == 'prepend') t.prepend(html); if(content == 'prepend') t.prepend(html);
else if(content == 'append') t.append(html); else if(content == 'append') t.append(html);
else if(content != 'hide') t.html(html); else if(content != 'hide') t.html(html);
web2py.trap_form(action, target); web2py.trap_form(action, target);
web2py.trap_link(target); web2py.trap_link(target);
web2py.ajax_init('#' + target); web2py.ajax_init('#' + target);
} }
@@ -275,10 +275,10 @@
var jelement = $("#" + target); var jelement = $("#" + target);
var element = jelement.get(0); var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();"; var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function () { jelement.reload = function () {
// Continue if times is Infinity or // Continue if times is Infinity or
// the times limit is not reached // the times limit is not reached
if(this.reload_check()) { if(element.reload_check()) {
web2py.ajax_page('get', action, null, target, el); web2py.ajax_page('get', action, null, target, el);
} }
}; // reload }; // reload
@@ -420,16 +420,16 @@
// replace element's html with the 'data-disable-with' after storing original html // replace element's html with the 'data-disable-with' after storing original html
// and prevent clicking on it // and prevent clicking on it
disableElement: function (el) { disableElement: function (el) {
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]);
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
} }
// set to disabled state // set to disabled state
el[method](el.data('w2p_disable_with')); el[method](el.data('w2p_disable_with'));
el.bind('click.w2pDisable', function (e) { // prevent further clicking el.bind('click.w2pDisable', function (e) { // prevent further clicking
return web2py.stopEverything(e); return web2py.stopEverything(e);
@@ -438,29 +438,52 @@
// restore element to its original state which was disabled by 'disableElement' above // restore element to its original state which was disabled by 'disableElement' above
enableElement: function (el) { 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) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
el.removeClass('disabled'); el.removeClass('disabled');
el.unbind('click.w2pDisable'); // enable element el.unbind('click.w2pDisable'); // enable element
}, },
//convenience wrapper, internal use only //convenience wrapper, internal use only
simple_component: function (action, target, element) { simple_component: function (action, target, element) {
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function(message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function() {
$('.flash').hide().html(''); $('.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) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
var method = el.data('w2p_method'); var method = el.data('w2p_method');
@@ -535,7 +558,7 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
@@ -543,10 +566,10 @@
disableFormElements: function(form) { disableFormElements: function(form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function() {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this), method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if (disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
element[method](element.data('w2p_disable_with')); element[method](element.data('w2p_disable_with'));
element.prop('disabled', true); element.prop('disabled', true);
@@ -554,8 +577,8 @@
}, },
/* Re-enables disabled form elements: /* Re-enables disabled form elements:
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function(form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function() {
@@ -564,15 +587,15 @@
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function() {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
}); });
el.on('ajax:complete', 'form[data-w2p_target]', function (e) { el.on('ajax:complete', 'form[data-w2p_target]', function (e) {
web2py.enableFormElements($(this)); web2py.enableFormElements($(this));
}); });
} }
} }
//end of functions //end of functions
@@ -584,7 +607,7 @@
web2py.ajax_init(document); web2py.ajax_init(document);
web2py.event_handlers(); web2py.event_handlers();
web2py.a_handlers(); web2py.a_handlers();
web2py.form_handlers(); web2py.form_handlers();
}); });
})(jQuery); })(jQuery);
+90 -67
View File
@@ -84,9 +84,9 @@
$("input.time", target).each(function () { $("input.time", target).each(function () {
$(this).timeEntry(); $(this).timeEntry();
}); });
/*adds btn class to buttons*/ /*adds btn class to buttons*/
$('button', target).addClass('btn'); $('button', target).addClass('btn');
$('form input[type="submit"], form input[type="button"]', target).addClass('btn'); $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
/*no more inline javascript for PasswordWidget*/ /*no more inline javascript for PasswordWidget*/
$('input[type=password][data-w2p_entropy]', target).each(function () { $('input[type=password][data-w2p_entropy]', target).each(function () {
web2py.validate_entropy($(this)); web2py.validate_entropy($(this));
@@ -143,24 +143,24 @@
$('.hidden', target).hide(); $('.hidden', target).hide();
web2py.manage_errors(target); web2py.manage_errors(target);
web2py.ajax_fields(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 () { event_handlers: function () {
/* This is called once for page /* This is called once for page
* Ideally it should bound all the things that are needed * Ideally it should bound all the things that are needed
*/ */
var doc = $(document); var doc = $(document);
doc.on('click', '.flash', function (e) { doc.on('click', '.flash', function (e) {
console.log('das');
var t = $(this); var t = $(this);
if(t.css('top') == '0px') t.slideUp('slow'); if(t.css('top') == '0px') t.slideUp('slow');
else t.fadeOut(); else t.fadeOut();
//if I want to display a clickable something //if I want to display a clickable something
//inside flash, I should not be prevented to follow it //inside flash, I should not be prevented to follow it
//e.preventDefault(); //e.preventDefault();
}); });
doc.on('keyup', 'input.integer', function () { doc.on('keyup', 'input.integer', function () {
@@ -185,15 +185,15 @@
eval(decodeURIComponent(command)); eval(decodeURIComponent(command));
} }
if(flash) { if(flash) {
web2py.flash(decodeURIComponent(flash)) web2py.flash(decodeURIComponent(flash))
} }
}); });
doc.ajaxError(function (e, xhr, settings, exception) { doc.ajaxError(function (e, xhr, settings, exception) {
//personally I don't like it. //personally I don't like it.
//if there's an error it it flashed and can be removed //if there's an error it it flashed and can be removed
//as any other message //as any other message
//doc.off('click', '.flash') //doc.off('click', '.flash')
switch(xhr.status) { switch(xhr.status) {
case 500: case 500:
web2py.flash(ajax_error_500); web2py.flash(ajax_error_500);
@@ -204,16 +204,16 @@
trap_form: function (action, target) { trap_form: function (action, target) {
$('#' + target + ' form').each(function (i) { $('#' + target + ' form').each(function (i) {
var form = $(this); var form = $(this);
form.attr('data-w2p_target', target); form.attr('data-w2p_target', target);
if(!form.hasClass('no_trap')) { if(!form.hasClass('no_trap')) {
//should be there by default ? //should be there by default ?
form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...'); form.find('input[type=submit]').attr('data-w2p_disable_with', 'Working...');
form.submit(function (e) { form.submit(function (e) {
web2py.hide_flash(); web2py.hide_flash();
web2py.ajax_page('post', action, form.serialize(), target, form); web2py.ajax_page('post', action, form.serialize(), target, form);
e.preventDefault(); e.preventDefault();
}); });
} }
}); });
}, },
trap_link: function (target) { trap_link: function (target) {
@@ -242,27 +242,27 @@
}, },
//added //added
'success': function (data, status, xhr) { 'success': function (data, status, xhr) {
//bummer for form submissions....the element is not there after complete //bummer for form submissions....the element is not there after complete
//because it gets replaced by the new response.... //because it gets replaced by the new response....
element.trigger('ajax:success', [data, status, xhr]); element.trigger('ajax:success', [data, status, xhr]);
}, },
//added //added
'error': function (xhr, status, error) { 'error': function (xhr, status, error) {
//bummer for form submissions....in addition to the element being not there after //bummer for form submissions....in addition to the element being not there after
//complete because it gets replaced by the new response, standard form //complete because it gets replaced by the new response, standard form
//handling just returns the same status code for good and bad //handling just returns the same status code for good and bad
//form submissions (i.e. that triggered a validator error) //form submissions (i.e. that triggered a validator error)
element.trigger('ajax:error', [xhr, status, error]); element.trigger('ajax:error', [xhr, status, error]);
}, },
'complete': function (xhr, status) { 'complete': function (xhr, status) {
element.trigger('ajax:complete', [xhr, status]); element.trigger('ajax:complete', [xhr, status]);
var html = xhr.responseText; var html = xhr.responseText;
var content = xhr.getResponseHeader('web2py-component-content'); var content = xhr.getResponseHeader('web2py-component-content');
var t = $('#' + target); var t = $('#' + target);
if(content == 'prepend') t.prepend(html); if(content == 'prepend') t.prepend(html);
else if(content == 'append') t.append(html); else if(content == 'append') t.append(html);
else if(content != 'hide') t.html(html); else if(content != 'hide') t.html(html);
web2py.trap_form(action, target); web2py.trap_form(action, target);
web2py.trap_link(target); web2py.trap_link(target);
web2py.ajax_init('#' + target); web2py.ajax_init('#' + target);
} }
@@ -275,10 +275,10 @@
var jelement = $("#" + target); var jelement = $("#" + target);
var element = jelement.get(0); var element = jelement.get(0);
var statement = "jQuery('#" + target + "').get(0).reload();"; var statement = "jQuery('#" + target + "').get(0).reload();";
element.reload = function () { jelement.reload = function () {
// Continue if times is Infinity or // Continue if times is Infinity or
// the times limit is not reached // the times limit is not reached
if(this.reload_check()) { if(element.reload_check()) {
web2py.ajax_page('get', action, null, target, el); web2py.ajax_page('get', action, null, target, el);
} }
}; // reload }; // reload
@@ -420,16 +420,16 @@
// replace element's html with the 'data-disable-with' after storing original html // replace element's html with the 'data-disable-with' after storing original html
// and prevent clicking on it // and prevent clicking on it
disableElement: function (el) { disableElement: function (el) {
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]);
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
} }
// set to disabled state // set to disabled state
el[method](el.data('w2p_disable_with')); el[method](el.data('w2p_disable_with'));
el.bind('click.w2pDisable', function (e) { // prevent further clicking el.bind('click.w2pDisable', function (e) { // prevent further clicking
return web2py.stopEverything(e); return web2py.stopEverything(e);
@@ -438,29 +438,52 @@
// restore element to its original state which was disabled by 'disableElement' above // restore element to its original state which was disabled by 'disableElement' above
enableElement: function (el) { 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) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
el.removeClass('disabled'); el.removeClass('disabled');
el.unbind('click.w2pDisable'); // enable element el.unbind('click.w2pDisable'); // enable element
}, },
//convenience wrapper, internal use only //convenience wrapper, internal use only
simple_component: function (action, target, element) { simple_component: function (action, target, element) {
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function(message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function() {
$('.flash').hide().html(''); $('.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) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
var method = el.data('w2p_method'); var method = el.data('w2p_method');
@@ -535,7 +558,7 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
@@ -543,10 +566,10 @@
disableFormElements: function(form) { disableFormElements: function(form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function() {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this), method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if (disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
element[method](element.data('w2p_disable_with')); element[method](element.data('w2p_disable_with'));
element.prop('disabled', true); element.prop('disabled', true);
@@ -554,8 +577,8 @@
}, },
/* Re-enables disabled form elements: /* Re-enables disabled form elements:
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function(form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function() {
@@ -564,15 +587,15 @@
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function() {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
}); });
el.on('ajax:complete', 'form[data-w2p_target]', function (e) { el.on('ajax:complete', 'form[data-w2p_target]', function (e) {
web2py.enableFormElements($(this)); web2py.enableFormElements($(this));
}); });
} }
} }
//end of functions //end of functions
@@ -584,7 +607,7 @@
web2py.ajax_init(document); web2py.ajax_init(document);
web2py.event_handlers(); web2py.event_handlers();
web2py.a_handlers(); web2py.a_handlers();
web2py.form_handlers(); web2py.form_handlers();
}); });
})(jQuery); })(jQuery);
+12 -57
View File
@@ -86,8 +86,8 @@ def show_if(cond):
if not cond: if not cond:
return None return None
base = "%s_%s" % (cond.first.tablename, cond.first.name) base = "%s_%s" % (cond.first.tablename, cond.first.name)
if ((cond.op.__name__ == 'EQ' and cond.second == True) or if ((cond.op.__name__ == 'EQ' and cond.second == True) or
(cond.op.__name__ == 'NE' and cond.second == False)): (cond.op.__name__ == 'NE' and cond.second == False)):
return base,":checked" return base,":checked"
if ((cond.op.__name__ == 'EQ' and cond.second == False) or if ((cond.op.__name__ == 'EQ' and cond.second == False) or
(cond.op.__name__ == 'NE' and cond.second == True)): (cond.op.__name__ == 'NE' and cond.second == True)):
@@ -97,7 +97,7 @@ def show_if(cond):
if cond.op.__name__ == 'NE': if cond.op.__name__ == 'NE':
return base,"[value!='%s']" % cond.second return base,"[value!='%s']" % cond.second
if cond.op.__name__ == 'CONTAINS': 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)): if cond.op.__name__ == 'BELONGS' and isinstance(cond.second,(list,tuple)):
return base,','.join("[value='%s']" % (v) for v in cond.second) return base,','.join("[value='%s']" % (v) for v in cond.second)
raise RuntimeError("Not Implemented Error") raise RuntimeError("Not Implemented Error")
@@ -126,7 +126,7 @@ class FormWidget(object):
_id='%s_%s' % (field.tablename, field.name), _id='%s_%s' % (field.tablename, field.name),
_class=cls._class or _class=cls._class or
widget_class.match(str(field.type)).group(), widget_class.match(str(field.type)).group(),
_name=field.name, _name=field.name,
requires=field.requires, requires=field.requires,
) )
if getattr(field,'show_if',None): if getattr(field,'show_if',None):
@@ -295,57 +295,15 @@ class ListWidget(StringWidget):
_class = 'string' _class = 'string'
requires = field.requires if isinstance( requires = field.requires if isinstance(
field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None
attributes['_style'] = 'list-style:none'
nvalue = value or [''] nvalue = value or ['']
items = [LI(INPUT(_id=_id, _class=_class, _name=_name, items = [LI(INPUT(_id=_id, _class=_class, _name=_name,
value=v, hideerror=k < len(nvalue) - 1, value=v, hideerror=k < len(nvalue) - 1,
requires=requires), requires=requires),
**attributes) for (k, v) in enumerate(nvalue)] **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('<a href="javascript:void(0)">+</a>&nbsp;<a href="javascript:void(0)">-</a>').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['_id'] = _id + '_grow_input'
attributes['_style'] = 'list-style:none' attributes['_style'] = 'list-style:none'
return TAG[''](UL(*items, **attributes), script) attributes['_class'] = 'w2p_list'
return TAG[''](UL(*items, **attributes))
class MultipleOptionsWidget(OptionsWidget): class MultipleOptionsWidget(OptionsWidget):
@@ -521,7 +479,6 @@ class PasswordWidget(FormWidget):
_value=(value and cls.DEFAULT_PASSWORD_DISPLAY) or '', _value=(value and cls.DEFAULT_PASSWORD_DISPLAY) or '',
) )
attr = cls._attributes(field, default, **attributes) attr = cls._attributes(field, default, **attributes)
output = CAT(INPUT(**attr))
# deal with entropy check! # deal with entropy check!
requires = field.requires requires = field.requires
@@ -529,10 +486,9 @@ class PasswordWidget(FormWidget):
requires = [requires] requires = [requires]
is_strong = [r for r in requires if isinstance(r, IS_STRONG)] is_strong = [r for r in requires if isinstance(r, IS_STRONG)]
if is_strong: if is_strong:
output.append(SCRIPT("web2py_validate_entropy(jQuery('#%s'),%s);" % ( attr['_data-w2p_entropy'] = is_strong[0].entropy if is_strong[0].entropy else "null"
attr['_id'], is_strong[0].entropy
if is_strong[0].entropy else "null")))
# end entropy check # end entropy check
output = INPUT(**attr)
return output return output
@@ -651,7 +607,7 @@ class AutocompleteWidget(object):
self.help_fields = help_fields or [] self.help_fields = help_fields or []
self.help_string = help_string self.help_string = help_string
if self.help_fields and not self.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) for f in self.help_fields)
self.request = request self.request = request
@@ -1484,7 +1440,7 @@ class SQLFORM(FORM):
continue continue
else: else:
f = os.path.join( f = os.path.join(
current.request.folder, current.request.folder,
os.path.normpath(f)) os.path.normpath(f))
source_file = open(f, 'rb') source_file = open(f, 'rb')
original_filename = os.path.split(f)[1] original_filename = os.path.split(f)[1]
@@ -2141,7 +2097,7 @@ class SQLFORM(FORM):
else: else:
rows = dbset.select(left=left, orderby=orderby, rows = dbset.select(left=left, orderby=orderby,
cacheable=True, *expcolumns) cacheable=True, *expcolumns)
value = exportManager[export_type] value = exportManager[export_type]
clazz = value[0] if hasattr(value, '__getitem__') else value clazz = value[0] if hasattr(value, '__getitem__') else value
oExp = clazz(rows) oExp = clazz(rows)
@@ -2694,7 +2650,7 @@ class SQLFORM(FORM):
elif grid.view_form: elif grid.view_form:
header = T('View %(entity)s') % dict( header = T('View %(entity)s') % dict(
entity=format(grid.view_form.table, entity=format(grid.view_form.table,
grid.view_form.record)) grid.view_form.record))
if next: if next:
breadcrumbs.append(LI( breadcrumbs.append(LI(
A(T(header), _class=trap_class(),_href=url()), A(T(header), _class=trap_class(),_href=url()),
@@ -3136,4 +3092,3 @@ class ExporterJSON(ExportClass):
return self.rows.as_json() return self.rows.as_json()
else: else:
return 'null' return 'null'