diff options
author | Alvin Li <liweitianux@gmail.com> | 2013-08-27 07:29:36 +0800 |
---|---|---|
committer | Alvin Li <liweitianux@gmail.com> | 2013-08-27 07:29:36 +0800 |
commit | 52eebfa317cdc80739a19485880c2308c36eed91 (patch) | |
tree | 81f02d1d358fc08ccc0cff04b021fa4ff9ec86e9 /97suifangqa/apps/indicator/static/javascripts/edit_history_data.js | |
parent | 58b77885308c944a029caf5c2d8b5d3263b6f64d (diff) | |
download | 97dev-52eebfa317cdc80739a19485880c2308c36eed91.tar.bz2 |
* added plugin 'qtip2' to provide 'tooltips';
employed in adding/modifying record data to provide validation info;
* added 'ajax_modify_record' url; removed 'ajax_edit_history_data' url;
* added 'indicator.views.ajax_modify_record()' for 'EditHistoryData.html';
* renamed 'indicator.views.add_recordhistory()' to 'add_recordhistory_view()';
* added 'indicator.tools.add_recordhistory()';
* added 'pytz' to 'env/requirements.pip';
'pytz' to handle timezone in python & django (recommended)
Diffstat (limited to '97suifangqa/apps/indicator/static/javascripts/edit_history_data.js')
-rw-r--r-- | 97suifangqa/apps/indicator/static/javascripts/edit_history_data.js | 436 |
1 files changed, 376 insertions, 60 deletions
diff --git a/97suifangqa/apps/indicator/static/javascripts/edit_history_data.js b/97suifangqa/apps/indicator/static/javascripts/edit_history_data.js index 83a87e2..f4deafd 100644 --- a/97suifangqa/apps/indicator/static/javascripts/edit_history_data.js +++ b/97suifangqa/apps/indicator/static/javascripts/edit_history_data.js @@ -1,3 +1,12 @@ +// global var to store the data of record +var record_data = { + date: null, + value: null, + val_min: null, + val_max: null, + reason: null +}; + $(document).ready(function(){ //点大叉,关闭弹层页面 $(".edit_history_data_close").bind("click", function(){ @@ -8,70 +17,98 @@ $(document).ready(function(){ $("#editing_date_picker").datepicker({ showOn: "both", buttonImage: static_url + "images/calendar.png", - buttonImageOnly: true + buttonImageOnly: true, + maxDate: 0 // 0->today, 1->tomorrow }); + // edit button $("#edit_btn").bind("click", function(){ var this_edit_data_div = $(this).closest(".edit_data"); - //var data_fir = $(this).siblings(".data_fir").text(); - //var data_sec = $(this).siblings(".data_sec").text(); - var data_fir = 0; - var data_sec = 0; var this_editing_data_div = this_edit_data_div.siblings(".editing_data"); - var input_container = this_editing_data_div.children(".input_container"); - input_container.children(".edit_input_main").val(parseInt(data_fir)); - input_container.children(".edit_input_sub").val(parseInt(data_sec)); this_editing_data_div.show(); this_edit_data_div.hide(); return false; }); - // save botton + + // save botton {{{ $("#save_btn").bind("click", function(){ - var data_input_fir = $(".edit_input_main"); - var data_input_sec = $(".edit_input_sub"); - var data_input_fir_val = data_input_fir.val(); - var data_input_sec_val = data_input_sec.val(); - - if(data_input_fir_val == '' || data_input_fir_val == 0){ - data_input_fir.addClass("error"); - }else{ - data_input_fir.removeClass("error"); - } - if(data_input_sec_val == ''){ - data_input_sec.addClass("error"); - }else{ - data_input_sec.removeClass("error"); - } - if($(".error").length > 0){ + // force to trigger 'validate' before save + $(".editing_data .to_validate").trigger('validate'); + if ($(".editing_data .invalid").length) { + // TODO: tooltip/popup return false; } - var time = moment().valueOf(); + // modified data validated + var cur_mm = moment(); + var created_at_str = cur_mm.toISOString(); + var time = cur_mm.valueOf(); $.ajax({ - type: 'get', - url: indicator_url + 'ajax/edit_history_data', - data: 'time='+time, - success: function(data){ - if(data == 'success'){ + type: 'post', + url: indicator_url + 'ajax/modify_record/', + data: { + csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value, + record_id: record_id, + date: record_data.date, + value: record_data.value, + val_min: record_data.val_min, + val_max: record_data.val_max, + reason: record_data.reason, + created_at: created_at_str, + time: time + }, + dataType: 'json', + success: function(dataJson) { + if (dataJson.failed == true) { + // tooltip + } + else { + // successfully modified parent.TB_remove(); + // update the detail chart //parent.redraw_chart(parent.detail_chart, "2013-08-04", "2013-08-10"); //这边需要穿过来起始,结束时间,以便刷新图表和表格 } } }); return false; }); + // }}} // set datepicker 'date_input' value var date_init = $.datepicker.parseDate('yy-mm-dd', $(".date_input").attr('value')); $(".date_input").datepicker("setDate", date_init); - // data validate {{{ - // validate date + // record data validate {{{ + // date {{{ + // date_input tooltip + var dateinput_help = '<p>日期格式:YYYY-MM-DD; 如:2013-08-26</p><p>日期不能晚于<strong>今天</strong></p>'; + $(".date_input").qtip({ + id: 'dateinput', // -> '#qtip-dateinput' + prerender: false, + content: { + text: dateinput_help + }, + position: { + my: 'bottom left', + at: 'top right' + }, + show: { + event: false + }, + hide: { + //event: 'click' + event: false + } + }); $(".date_input").focus(function() { $(this).removeClass("valid invalid"); + // show help tooltip + var qtip_content = dateinput_help; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); }); - $(".date_input").change(function() { + $(".date_input").on('validate', null, function() { var date_str = $(this).val(); var date_mm = moment(date_str, 'YYYY-MM-DD'); var today_mm = moment(); @@ -80,56 +117,261 @@ $(document).ready(function(){ if (date_mm.isValid() && !date_mm.isAfter(today_mm)) { $(this).removeClass("invalid"); $(this).addClass("valid"); + $(this).qtip('api').hide(); + // update data + record_data.date = date_str; } else { // date invalid $(this).removeClass("valid"); $(this).addClass("invalid"); + var qtip_content = '<p>请检查输入日期的格式,并且日期不能晚于<strong>今天</strong></p>'; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); } }); - // validate data - $(".data_input").focus(function() { - $(this).removeClass("valid invalid"); - }); - $(".data_input").change(function() { - //$(this).removeClass("valid invalid"); + $(".date_input").on('change blur', null, function() { + $(this).trigger('validate'); }); + // }}} + + // validate data + if (data_type == DATA_TYPES.INTEGER_TYPE) { + // INTEGER_TYPE + // TODO + } + else if (data_type == DATA_TYPES.FLOAT_TYPE) { // {{{ + // FLOAT_TYPE + var datainput_help = '<p>定值型</p><p>数据格式示例:123.7; 1.23e4; 3.5e-2</p>'; + // tooltip + $(".data_input").qtip({ + id: 'datainput', + prerender: false, + content: { + text: datainput_help + }, + position: { + my: 'bottom left', + at: 'top right' + }, + show: { + event: false + }, + hide: { + //event: 'click' + event: false + } + }); + $(".data_input").focus(function() { + $(this).removeClass("valid invalid"); + // show help tooltip + var qtip_content = datainput_help; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); + }); + // validate + $(".data_input").on('validate', null, function() { + var value_str = $(this).val(); + var value = is_float(value_str); + if (value === false) { + // format invalid + $(this).removeClass("valid"); + $(this).addClass("invalid"); + var qtip_content = '<p>数据格式不符合要求,请检查后重新输入</p>'; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); + } + else { + // format valid + // check confine + if (value >= confine.math_min && + value <= confine.math_max) { + // confine valid + $(this).removeClass("invalid"); + $(this).addClass("valid"); + $(this).qtip('api').hide(); + // update data + record_data.value = value; + } + else { + // confine tooltip + $(this).removeClass("valid"); + $(this).addClass("invalid"); + var qtip_content = '<p>数值超出范围</p><p>允许数据范围:'+confine.math_range_html+' </p>'; + $(this).qtip('api').set('content.text', + qtip_content); + $(this).qtip('api').show(); + } + } + }); + $(".data_input").on('blur', null, function() { + $(this).trigger('validate'); + }); + } // }}} + else if (data_type == DATA_TYPES.RANGE_TYPE) { // {{{ + // RANGE_TYPE + var datainput_help = '<p>范围型</p><p>数据格式示例:• <123.7; • >1.3e3; • 1.5e3 ~ 3.7e3</p>'; + // tooltip + $(".data_input").qtip({ + id: 'datainput', + prerender: false, + content: { + text: datainput_help + }, + position: { + my: 'bottom left', + at: 'top right' + }, + show: { + event: false + }, + hide: { + //event: 'click' + event: false + } + }); + $(".data_input").focus(function() { + $(this).removeClass("valid invalid"); + // show help tooltip + var qtip_content = datainput_help; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); + }); + // validate + $(".data_input").on('validate', null, function() { + var value_str = $(this).val(); + var value = is_range(value_str); + if (is_range(value_str) === false) { + // format invalid + $(this).removeClass("valid"); + $(this).addClass("invalid"); + var qtip_content = '<p>数据格式不符合要求,请检查后重新输入</p>'; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); + } + else { + // range format valid + // check if within 'confine' + var confine_valid = false; + var val_min = null; + var val_max = null; + + var operator = value.operator; + if (operator === '<') { + val_max = value.value; + if (val_max > confine.math_min && + val_max <= confine.math_max) { + // valid + confine_valid = true; + val_min = confine.math_min; + } + } + else if (operator === '>') { + val_min = value.value; + if (val_min >= confine.math_min && + val_min < confine.math_max) { + // valid + confine_valid = true; + val_max = confine.math_max; + } + } + else if (operator === '~') { + val_min = value.val_min; + val_max = value.val_max; + if (val_min >= confine.math_min && + val_max < confine.math_max) { + // valid + confine_valid = true; + } + } + else { + confine_valid = false; + } + + if (confine_valid === true) { + $(this).removeClass("invalid"); + $(this).addClass("valid"); + $(this).qtip('api').hide(); + // update data + record_data.val_min = val_min; + record_data.val_max = val_max; + } + else { + // data not within range + $(this).removeClass("valid"); + $(this).addClass("invalid"); + var qtip_content = '<p>数值超出范围</p><p>允许数据范围:'+confine.math_range_html+' </p>'; + $(this).qtip('api').set('content.text', + qtip_content); + $(this).qtip('api').show(); + } + } + }); + $(".data_input").on('blur', null, function() { + $(this).trigger('validate'); + }); + } // RANGE_TYPE }}} + else if (data_type == DATA_TYPES.FLOAT_RANGE_TYPE) { + // TODO + } + else if (data_type == DATA_TYPES.PM_TYPE) { + // TODO + } + else { + // unknown + return false; + } + // validate reason + var reasoninput_help = '<p><strong>必填</strong></p>'; + $(".reason_input").qtip({ + id: 'reasoninput', + prerender: false, + content: { + text: reasoninput_help + }, + position: { + my: 'bottom left', + at: 'top right' + }, + show: { + event: false + }, + hide: { + //event: 'click' + event: false + } + }); $(".reason_input").focus(function() { $(this).removeClass("valid invalid"); + // show help tooltip + var qtip_content = dateinput_help; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); }); - $(".reason_input").blur(function() { + $(".reason_input").on('validate', null, function() { var reason_str = $(this).val(); if (is_str_blank(reason_str)) { // reason not given or blank $(this).removeClass("valid"); $(this).addClass("invalid"); + var qtip_content = '<p>未输入内容,或为空白内容</p><p>请重新输入</p>'; + $(this).qtip('api').set('content.text', qtip_content); + $(this).qtip('api').show(); } else { - // reason given and not blank + // valid $(this).removeClass("invalid"); $(this).addClass("valid"); + $(this).qtip('api').hide(); + // update data + record_data.reason = reason_str; } }); - // }}} - - //编辑数据的底数验证:只允许两位小数,非空 - $(".edit_input_main").bind("keyup", function(){ - var val = $(this).val(); - val = val.replace(/[^\d.]/g,""); //清除"数字"和"."以外的字符 - val = val.replace(/^\./g,""); //验证第一个字符是数字而不是.. - val = val.replace(/\.{2,}/g,"."); //只保留第一个. 清除多余的 - val = val.replace(".","$#$").replace(/\./g,"").replace("$#$","."); - val = val.replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3'); - $(this).val(val); - return false; - }); - //编辑数据的指数验证:只允许整数 - $(".edit_input_sub").bind("keyup", function(){ - var val = $(this).val().replace(/[^\d]/g, ''); - $(this).val(val); - return false; + $(".reason_input").on('blur', null, function() { + $(this).trigger('validate'); }); + // }}} }); // help functions @@ -143,4 +385,78 @@ function is_str_blank(str) { return (!str || /^\s*$/.test(str)); } +// check if a string is float number // {{{ +function is_float(str) { + // regex for fixed notation float number + var fix_regex = /^([+-]?)(\d+|\d+(\.\d*)?|\d*\.\d+)$/; + // regex for exponential notation float number + var exp_regex = /^([+-]?)(\d+|\d+(\.\d*)?|\d*\.\d+)[eE]([+-]?)\d+$/;; + + str = str || ""; + var str_orig = str; + //console.log('str_orig: "'+str_orig+'"'); + // remove the blank on the head and tail + str = str.replace(/(^\s*|\s*$)/g, ''); + // remove blank between sign and number + str = str.replace(/^([+-]?)\s*/, '$1'); + //console.log('str: "'+str+'"'); + // valid str can only contains '[\d.]', '[+-]?', and '[eE]?' + if (fix_regex.test(str) || exp_regex.test(str)) { + // true + return parseFloat(str); + } + else { + return false; + } +} +// }}} + +// check if a string is valid range +// a) '< num'; b) '> num'; c) 'low ~ high' (range_symbol) // {{{ +function is_range(str) { + if (typeof range_symbol === 'undefined') { + range_symbol = '~'; + } + str = str || ""; + var str_orig = str; + + str = str.replace(/(^\s*|\s*$)/g, ''); + var operator = str.charAt(0); + if (operator === '<' || operator === '>') { + // strip the first char + str = str.replace(/^./, ''); + var value = is_float(str); + if (value === false) { + return false; + } + else { + return {'operator': operator, 'value': value}; + } + } + else { + // not case 'a)' & 'b)' + var str_splited = str.split(range_symbol); + if (str_splited.length == 2) { + var val_min = is_float(str_splited[0]); + var val_max = is_float(str_splited[1]); + if (val_min !== false && val_max !== false + && val_min < val_max) { + // valid + operator = range_symbol; + return {'operator': operator, + 'val_min': val_min, + 'val_max': val_max }; + } + else { + return false; + } + } + else { + // invalid + return false + } + } +} +// }}} + // vim: set ts=4 sw=4 tw=0 fenc=utf-8 ft=javascript: // |