From ee96a9753af9181d78f420d59b1676f7ffd6ae50 Mon Sep 17 00:00:00 2001 From: Peter Pfeufer Date: Thu, 18 Jan 2024 19:07:08 +0100 Subject: [PATCH] [CHANGE] Switch to x-editable v1.5.4 for Bootstrap 5 compatibility --- .../aasrp/javascript/aa-srp-view-requests.js | 4 +- .../javascript/aa-srp-view-requests.min.js | 2 +- .../aa-srp-view-requests.min.js.map | 2 +- .../css/bootstrap-editable.min.css | 15 - .../js/bootstrap-editable.js | 6883 ----------------- .../js/bootstrap-editable.min.js | 1 - .../css/bootstrap-editable.css | 471 +- .../css/bootstrap-editable.min.css | 16 + .../css/bootstrap-editable.min.css.map | 1 + .../bootstrap5-editable}/img/clear.png | Bin .../bootstrap5-editable}/img/loading.gif | Bin .../js/bootstrap-editable.js | 6731 ++++++++++++++++ .../js/bootstrap-editable.min.js | 2 + .../js/bootstrap-editable.min.js.map | 1 + .../aasrp/bundles/x-editable-css.html | 2 +- .../aasrp/bundles/x-editable-js.html | 2 +- 16 files changed, 6988 insertions(+), 7145 deletions(-) delete mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/css/bootstrap-editable.min.css delete mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/js/bootstrap-editable.js delete mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/js/bootstrap-editable.min.js rename aasrp/static/aasrp/libs/x-editable/{1.5.3/bootstrap3-editable => 1.5.4/bootstrap5-editable}/css/bootstrap-editable.css (59%) create mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.4/bootstrap5-editable/css/bootstrap-editable.min.css create mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.4/bootstrap5-editable/css/bootstrap-editable.min.css.map rename aasrp/static/aasrp/libs/x-editable/{1.5.3/bootstrap3-editable => 1.5.4/bootstrap5-editable}/img/clear.png (100%) rename aasrp/static/aasrp/libs/x-editable/{1.5.3/bootstrap3-editable => 1.5.4/bootstrap5-editable}/img/loading.gif (100%) create mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.4/bootstrap5-editable/js/bootstrap-editable.js create mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.4/bootstrap5-editable/js/bootstrap-editable.min.js create mode 100644 aasrp/static/aasrp/libs/x-editable/1.5.4/bootstrap5-editable/js/bootstrap-editable.min.js.map diff --git a/aasrp/static/aasrp/javascript/aa-srp-view-requests.js b/aasrp/static/aasrp/javascript/aa-srp-view-requests.js index a4e2693d..18f913b8 100644 --- a/aasrp/static/aasrp/javascript/aa-srp-view-requests.js +++ b/aasrp/static/aasrp/javascript/aa-srp-view-requests.js @@ -183,7 +183,7 @@ $(document).ready(() => { `{csrfmiddlewaretoken:'${aaSrpSettings.csrfToken}'}` ) .attr('data-pk', srpRequestCode) - .attr('data-tooltip', 'enable') + // .attr('data-bs-title', aaSrpSettings.translation.changeSrpPayoutAmount) .attr('title', aaSrpSettings.translation.changeSrpPayoutAmount) .attr( 'data-url', @@ -269,7 +269,7 @@ $(document).ready(() => { }); // Show bootstrap tooltips - $('[data-tooltip="enable"]').tooltip(); + // $('[data-tooltip="enable"]').tooltip(); }); /** diff --git a/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js b/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js index 78c15edf..d606e2cf 100644 --- a/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js +++ b/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js @@ -1,2 +1,2 @@ -$(document).ready(()=>{"use strict";const e=$("#tab_aasrp_srp_requests"),n=e.DataTable({ajax:{url:aaSrpSettings.url.requestsForSrpLink,dataSrc:"",cache:!1},columns:[{data:"request_time",render:e=>moment(e).utc().format(aaSrpSettings.datetimeFormat),className:"srp-request-time"},{data:"requester",className:"srp-request-requester"},{data:"character_html",render:{display:"display",_:"sort"},className:"srp-request-character"},{data:"request_code",className:"srp-request-code"},{data:"ship_html",render:{display:"display",_:"sort"},className:"srp-request-ship"},{data:"zbk_loss_amount",render:(e,t)=>"display"===t?e.toLocaleString()+" ISK":e,className:"srp-request-zbk-loss-amount text-end"},{data:"payout_amount",render:(e,t)=>"display"===t?`${e.toLocaleString()} ISK`:e,className:"srp-request-payout text-end"},{data:"request_status_icon",className:"srp-request-status text-center"},{data:"actions",className:"srp-request-actions text-end"},{data:"ship"},{data:"request_status"},{data:"character"}],columnDefs:[{orderable:!1,targets:[7,8]},{visible:!1,targets:[9,10,11]},{width:115,targets:[8]}],order:[[0,"asc"]],filterDropDown:{columns:[{idx:1},{idx:11,title:aaSrpSettings.translation.filter.character},{idx:9,title:aaSrpSettings.translation.filter.ship},{idx:10,title:aaSrpSettings.translation.filter.requestStatus}],autoSize:!1,bootstrap:!0,bootstrap_version:5},paging:!1,createdRow:(e,t,a)=>{const r=t.request_code,s=t.request_status.toLowerCase(),o=t.payout_amount;$(e).attr("data-row-id",a).attr("data-srp-request-code",r).addClass("srp-request-status-"+s),$(e).find("span.srp-payout-amount").attr("data-value",o),"pending"!==s&&"rejected"!==s||($(e).find("td.srp-request-payout").addClass("srp-request-payout-amount-editable"),$(e).find("span.srp-payout-amount").addClass("srp-request-"+r).attr("data-params",`{csrfmiddlewaretoken:'${aaSrpSettings.csrfToken}'}`).attr("data-pk",r).attr("data-tooltip","enable").attr("title",aaSrpSettings.translation.changeSrpPayoutAmount).attr("data-url",aaSrpSettings.url.changeSrpAmount.replace("SRP_REQUEST_CODE",r)))}}),a=(e,t)=>{const a=(t=parseInt(t)).toLocaleString()+" ISK";e.attr("data-value",t).addClass("srp-payout-amount-changed").html(a);let r=0;const s=$("#tab_aasrp_srp_requests .srp-request-status-approved .srp-payout-amount");s.each((e,t)=>{r+=parseInt(t.getAttribute("data-value"))}),$(".srp-fleet-total-amount").html(r.toLocaleString()+" ISK")},d=(n.on("draw",()=>{e.editable({container:"body",selector:".srp-request-payout-amount-editable .srp-payout-amount",title:aaSrpSettings.translation.changeSrpPayoutHeader,type:"number",placement:"top",display:()=>!1,success:function(e,t){a($(this),t)},validate:e=>{if(""===e)return aaSrpSettings.translation.editableValidate}}),$('[data-tooltip="enable"]').tooltip()}),e=>{let a=0,r=0,s=0,o=0,n=0;$.each(e,(e,t)=>{r+=1,"Pending"===t.request_status&&(s+=1),"Approved"===t.request_status&&(a+=parseInt(t.payout_amount),o+=1),"Rejected"===t.request_status&&(n+=1)}),$(".srp-fleet-total-amount").html(a.toLocaleString()+" ISK"),$(".srp-requests-total-count").html(r),$(".srp-requests-pending-count").html(s),$(".srp-requests-approved-count").html(o),$(".srp-requests-rejected-count").html(n)}),r=$("#srp-request-details"),o=$("#srp-request-accept"),i=$("#srp-request-accept-rejected"),l=$("#srp-request-reject"),s=$("#srp-request-remove");r.on("show.bs.modal",e=>{const t=$(e.relatedTarget),a=t.data("link");$.get({url:a,success:e=>{r.find(".modal-body").html(e)}})}).on("hide.bs.modal",()=>{r.find(".modal-body").text("")}),o.on("show.bs.modal",e=>{const t=$(e.relatedTarget),s=t.data("link");$("#modal-button-confirm-accept-request").on("click",()=>{const e=o.find("form"),t=e.find('textarea[name="reviser_comment"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val(),r=$.post(s,{reviser_comment:t,csrfmiddlewaretoken:a});r.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),o.modal("hide")})}).on("hide.bs.modal",()=>{o.find('textarea[name="reject_info"]').val(""),$("#modal-button-confirm-accept-request").unbind("click")}),i.on("show.bs.modal",e=>{const t=$(e.relatedTarget),o=t.data("link");$("#modal-button-confirm-accept-rejected-request").on("click",()=>{const e=i.find("form"),t=e.find('textarea[name="reviser_comment"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val();if(""===t){const r=`

${aaSrpSettings.translation.modal.form.error.fieldRequired}

`;e.find(".aasrp-form-field-errors").remove(),$(r).insertAfter($('textarea[name="reviser_comment"]'))}else{const s=$.post(o,{reviser_comment:t,csrfmiddlewaretoken:a});s.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),i.modal("hide")}})}).on("hide.bs.modal",()=>{i.find('textarea[name="reviser_comment"]').val(""),$(".aasrp-form-field-errors").remove(),$("#modal-button-confirm-accept-rejected-request").unbind("click")}),l.on("show.bs.modal",e=>{const t=$(e.relatedTarget),o=t.data("link");$("#modal-button-confirm-reject-request").on("click",()=>{const e=l.find("form"),t=e.find('textarea[name="reject_info"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val();if(""===t){const r=`

${aaSrpSettings.translation.modal.form.error.fieldRequired}

`;e.find(".aasrp-form-field-errors").remove(),$(r).insertAfter($('textarea[name="reject_info"]'))}else{const s=$.post(o,{reject_info:t,csrfmiddlewaretoken:a});s.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),l.modal("hide")}})}).on("hide.bs.modal",()=>{l.find('textarea[name="reject_info"]').val(""),$(".aasrp-form-field-errors").remove(),$("#modal-button-confirm-reject-request").unbind("click")}),s.on("show.bs.modal",e=>{const t=$(e.relatedTarget),a=t.data("link");$("#modal-button-confirm-remove-request").on("click",()=>{$.get(a,e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),s.modal("hide")})}).on("hide.bs.modal",()=>{s.find('textarea[name="reject_info"]').val(""),$("#modal-button-confirm-remove-request").unbind("click")})}); +$(document).ready(()=>{"use strict";const e=$("#tab_aasrp_srp_requests"),n=e.DataTable({ajax:{url:aaSrpSettings.url.requestsForSrpLink,dataSrc:"",cache:!1},columns:[{data:"request_time",render:e=>moment(e).utc().format(aaSrpSettings.datetimeFormat),className:"srp-request-time"},{data:"requester",className:"srp-request-requester"},{data:"character_html",render:{display:"display",_:"sort"},className:"srp-request-character"},{data:"request_code",className:"srp-request-code"},{data:"ship_html",render:{display:"display",_:"sort"},className:"srp-request-ship"},{data:"zbk_loss_amount",render:(e,t)=>"display"===t?e.toLocaleString()+" ISK":e,className:"srp-request-zbk-loss-amount text-end"},{data:"payout_amount",render:(e,t)=>"display"===t?`${e.toLocaleString()} ISK`:e,className:"srp-request-payout text-end"},{data:"request_status_icon",className:"srp-request-status text-center"},{data:"actions",className:"srp-request-actions text-end"},{data:"ship"},{data:"request_status"},{data:"character"}],columnDefs:[{orderable:!1,targets:[7,8]},{visible:!1,targets:[9,10,11]},{width:115,targets:[8]}],order:[[0,"asc"]],filterDropDown:{columns:[{idx:1},{idx:11,title:aaSrpSettings.translation.filter.character},{idx:9,title:aaSrpSettings.translation.filter.ship},{idx:10,title:aaSrpSettings.translation.filter.requestStatus}],autoSize:!1,bootstrap:!0,bootstrap_version:5},paging:!1,createdRow:(e,t,a)=>{const r=t.request_code,s=t.request_status.toLowerCase(),o=t.payout_amount;$(e).attr("data-row-id",a).attr("data-srp-request-code",r).addClass("srp-request-status-"+s),$(e).find("span.srp-payout-amount").attr("data-value",o),"pending"!==s&&"rejected"!==s||($(e).find("td.srp-request-payout").addClass("srp-request-payout-amount-editable"),$(e).find("span.srp-payout-amount").addClass("srp-request-"+r).attr("data-params",`{csrfmiddlewaretoken:'${aaSrpSettings.csrfToken}'}`).attr("data-pk",r).attr("title",aaSrpSettings.translation.changeSrpPayoutAmount).attr("data-url",aaSrpSettings.url.changeSrpAmount.replace("SRP_REQUEST_CODE",r)))}}),a=(e,t)=>{const a=(t=parseInt(t)).toLocaleString()+" ISK";e.attr("data-value",t).addClass("srp-payout-amount-changed").html(a);let r=0;const s=$("#tab_aasrp_srp_requests .srp-request-status-approved .srp-payout-amount");s.each((e,t)=>{r+=parseInt(t.getAttribute("data-value"))}),$(".srp-fleet-total-amount").html(r.toLocaleString()+" ISK")},d=(n.on("draw",()=>{e.editable({container:"body",selector:".srp-request-payout-amount-editable .srp-payout-amount",title:aaSrpSettings.translation.changeSrpPayoutHeader,type:"number",placement:"top",display:()=>!1,success:function(e,t){a($(this),t)},validate:e=>{if(""===e)return aaSrpSettings.translation.editableValidate}})}),e=>{let a=0,r=0,s=0,o=0,n=0;$.each(e,(e,t)=>{r+=1,"Pending"===t.request_status&&(s+=1),"Approved"===t.request_status&&(a+=parseInt(t.payout_amount),o+=1),"Rejected"===t.request_status&&(n+=1)}),$(".srp-fleet-total-amount").html(a.toLocaleString()+" ISK"),$(".srp-requests-total-count").html(r),$(".srp-requests-pending-count").html(s),$(".srp-requests-approved-count").html(o),$(".srp-requests-rejected-count").html(n)}),r=$("#srp-request-details"),o=$("#srp-request-accept"),i=$("#srp-request-accept-rejected"),l=$("#srp-request-reject"),s=$("#srp-request-remove");r.on("show.bs.modal",e=>{const t=$(e.relatedTarget),a=t.data("link");$.get({url:a,success:e=>{r.find(".modal-body").html(e)}})}).on("hide.bs.modal",()=>{r.find(".modal-body").text("")}),o.on("show.bs.modal",e=>{const t=$(e.relatedTarget),s=t.data("link");$("#modal-button-confirm-accept-request").on("click",()=>{const e=o.find("form"),t=e.find('textarea[name="reviser_comment"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val(),r=$.post(s,{reviser_comment:t,csrfmiddlewaretoken:a});r.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),o.modal("hide")})}).on("hide.bs.modal",()=>{o.find('textarea[name="reject_info"]').val(""),$("#modal-button-confirm-accept-request").unbind("click")}),i.on("show.bs.modal",e=>{const t=$(e.relatedTarget),o=t.data("link");$("#modal-button-confirm-accept-rejected-request").on("click",()=>{const e=i.find("form"),t=e.find('textarea[name="reviser_comment"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val();if(""===t){const r=`

${aaSrpSettings.translation.modal.form.error.fieldRequired}

`;e.find(".aasrp-form-field-errors").remove(),$(r).insertAfter($('textarea[name="reviser_comment"]'))}else{const s=$.post(o,{reviser_comment:t,csrfmiddlewaretoken:a});s.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),i.modal("hide")}})}).on("hide.bs.modal",()=>{i.find('textarea[name="reviser_comment"]').val(""),$(".aasrp-form-field-errors").remove(),$("#modal-button-confirm-accept-rejected-request").unbind("click")}),l.on("show.bs.modal",e=>{const t=$(e.relatedTarget),o=t.data("link");$("#modal-button-confirm-reject-request").on("click",()=>{const e=l.find("form"),t=e.find('textarea[name="reject_info"]').val(),a=e.find('input[name="csrfmiddlewaretoken"]').val();if(""===t){const r=`

${aaSrpSettings.translation.modal.form.error.fieldRequired}

`;e.find(".aasrp-form-field-errors").remove(),$(r).insertAfter($('textarea[name="reject_info"]'))}else{const s=$.post(o,{reject_info:t,csrfmiddlewaretoken:a});s.done(e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),l.modal("hide")}})}).on("hide.bs.modal",()=>{l.find('textarea[name="reject_info"]').val(""),$(".aasrp-form-field-errors").remove(),$("#modal-button-confirm-reject-request").unbind("click")}),s.on("show.bs.modal",e=>{const t=$(e.relatedTarget),a=t.data("link");$("#modal-button-confirm-remove-request").on("click",()=>{$.get(a,e=>{!0===e[0].success&&n.ajax.reload(e=>{d(e)})}),s.modal("hide")})}).on("hide.bs.modal",()=>{s.find('textarea[name="reject_info"]').val(""),$("#modal-button-confirm-remove-request").unbind("click")})}); //# sourceMappingURL=aa-srp-view-requests.min.js.map \ No newline at end of file diff --git a/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js.map b/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js.map index c2fb53e0..6b86fc6a 100644 --- a/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js.map +++ b/aasrp/static/aasrp/javascript/aa-srp-view-requests.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["aa-srp-view-requests.js"],"names":["$","document","ready","elementSrpRequestsTable","srpRequestsTable","DataTable","ajax","url","aaSrpSettings","requestsForSrpLink","dataSrc","cache","columns","data","render","moment","utc","format","datetimeFormat","className","display","_","type","toLocaleString","columnDefs","orderable","targets","visible","width","order","filterDropDown","idx","title","translation","filter","character","ship","requestStatus","autoSize","bootstrap","bootstrap_version","paging","createdRow","row","rowIndex","srpRequestCode","request_code","srpRequestStatus","request_status","toLowerCase","srpRequestPayoutAmount","payout_amount","attr","addClass","find","csrfToken","changeSrpPayoutAmount","changeSrpAmount","replace","_refreshSrpAmountField","element","newValue","newValueFormatted","parseInt","html","let","totalSrpAmount","elementSrpAmount","each","i","payoutElement","getAttribute","_reloadSrpCalculations","on","editable","container","selector","changeSrpPayoutHeader","placement","success","response","this","validate","value","editableValidate","tooltip","requestsTotal","requestsPending","requestsApproved","requestsRejected","tableData","item","modalSrpRequestDetails","modalSrpRequestAccept","modalSrpRequestAcceptRejected","modalSrpRequestReject","modalSrpRequestRemove","button","event","relatedTarget","get","text","form","reviserComment","val","csrfMiddlewareToken","posting","post","reviser_comment","csrfmiddlewaretoken","done","reload","modal","unbind","errorMessage","error","fieldRequired","remove","insertAfter","rejectInfo","reject_info"],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["aa-srp-view-requests.js"],"names":["$","document","ready","elementSrpRequestsTable","srpRequestsTable","DataTable","ajax","url","aaSrpSettings","requestsForSrpLink","dataSrc","cache","columns","data","render","moment","utc","format","datetimeFormat","className","display","_","type","toLocaleString","columnDefs","orderable","targets","visible","width","order","filterDropDown","idx","title","translation","filter","character","ship","requestStatus","autoSize","bootstrap","bootstrap_version","paging","createdRow","row","rowIndex","srpRequestCode","request_code","srpRequestStatus","request_status","toLowerCase","srpRequestPayoutAmount","payout_amount","attr","addClass","find","csrfToken","changeSrpPayoutAmount","changeSrpAmount","replace","_refreshSrpAmountField","element","newValue","newValueFormatted","parseInt","html","let","totalSrpAmount","elementSrpAmount","each","i","payoutElement","getAttribute","_reloadSrpCalculations","on","editable","container","selector","changeSrpPayoutHeader","placement","success","response","this","validate","value","editableValidate","requestsTotal","requestsPending","requestsApproved","requestsRejected","tableData","item","modalSrpRequestDetails","modalSrpRequestAccept","modalSrpRequestAcceptRejected","modalSrpRequestReject","modalSrpRequestRemove","button","event","relatedTarget","get","text","form","reviserComment","val","csrfMiddlewareToken","posting","post","reviser_comment","csrfmiddlewaretoken","done","reload","modal","unbind","errorMessage","error","fieldRequired","remove","insertAfter","rejectInfo","reject_info"],"mappings":"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"} \ No newline at end of file diff --git a/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/css/bootstrap-editable.min.css b/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/css/bootstrap-editable.min.css deleted file mode 100644 index 6ede830f..00000000 --- a/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/css/bootstrap-editable.min.css +++ /dev/null @@ -1,15 +0,0 @@ -/*! X-editable - v1.5.3 -* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery -* http://github.com/vitalets/x-editable -* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */ -.editableform{margin-bottom:0}.editableform .control-group{margin-bottom:0;white-space:nowrap;line-height:20px}.form-horizontal .editable-popup .editableform .form-group{margin-left:0;margin-right:0}.editableform .form-control{width:auto}.editable-buttons,.editable-input{vertical-align:top;display:inline-block;zoom:1;*display:inline}.editable-buttons{margin-left:7px}.editable-buttons.editable-buttons-bottom{display:block;margin-top:7px;margin-left:0}.editable-input{width:auto;white-space:normal}.editable-buttons .editable-cancel{margin-left:7px}.editable-buttons button.ui-button-icon-only{height:24px;width:30px}.editableform-loading{background:url(../img/loading.gif) center center no-repeat;height:25px;width:auto;min-width:25px}.editable-inline .editableform-loading{background-position:left 5px}.editable-error-block{max-width:300px;margin:5px 0 0;width:auto;white-space:normal}.editable-error-block.ui-state-error{padding:3px}.editable-error{color:red}.editableform .editable-date{padding:0;margin:0;float:left}.editable-inline .add-on .icon-th{margin-top:3px;margin-left:1px}.editable-checklist label input[type=checkbox],.editable-checklist label span{vertical-align:middle;margin:0}.editable-checklist label{white-space:nowrap}.editable-wysihtml5{width:566px;height:250px}.editable-clear{clear:both;font-size:.9em;text-decoration:none;text-align:right}.editable-clear-x{background:url(../img/clear.png) center center no-repeat;display:block;width:13px;height:13px;position:absolute;opacity:.6;z-index:100;top:50%;right:6px;margin-top:-6px}.editable-clear-x:hover{opacity:1}.editable-pre-wrapped{white-space:pre-wrap}.editable-container.editable-popup{max-width:none!important}.editable-container.popover{width:auto}.editable-container.editable-inline{display:inline-block;vertical-align:middle;width:auto;zoom:1;*display:inline}.editable-container.ui-widget{font-size:inherit;z-index:9990}.editable-click,a.editable-click,a.editable-click:hover{text-decoration:none;border-bottom:dashed 1px #08c}.editable-click.editable-disabled,a.editable-click.editable-disabled,a.editable-click.editable-disabled:hover{color:#585858;cursor:default;border-bottom:none}.editable-empty,.editable-empty:focus,.editable-empty:hover{font-style:italic;color:#d14;text-decoration:none}.editable-unsaved{font-weight:700}.editable-bg-transition{-webkit-transition:background-color 1400ms ease-out;-moz-transition:background-color 1400ms ease-out;-o-transition:background-color 1400ms ease-out;-ms-transition:background-color 1400ms ease-out;transition:background-color 1400ms ease-out}.form-horizontal .editable{padding-top:5px;display:inline-block} -/*! - * Datepicker for Bootstrap - * - * Copyright 2012 Stefan Petre - * Improvements by Andrew Rowls - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - */ -.datepicker{padding:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;direction:ltr}.datepicker-inline{width:220px}.datepicker.datepicker-rtl{direction:rtl}.datepicker.datepicker-rtl table tr td span{float:right}.datepicker-dropdown{top:0;left:0}.datepicker-dropdown:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:6px}.datepicker-dropdown:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.datepicker>div{display:none}.datepicker.days div.datepicker-days,.datepicker.months div.datepicker-months,.datepicker.years div.datepicker-years{display:block}.datepicker table{margin:0}.datepicker table tr td span,.datepicker td,.datepicker th{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.datepicker td,.datepicker th{text-align:center;width:20px;height:20px;border:0}.table-striped .datepicker table tr td,.table-striped .datepicker table tr th{background-color:transparent}.datepicker table tr td.day:hover{background:#eee;cursor:pointer}.datepicker table tr td.new,.datepicker table tr td.old{color:#999}.datepicker table tr td.disabled,.datepicker table tr td.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td.today{background-color:#fde19a}.datepicker table tr td.today,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today:hover{background-image:-moz-linear-gradient(top,#fdd49a,#fdf59a);background-image:-ms-linear-gradient(top,#fdd49a,#fdf59a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdd49a),to(#fdf59a));background-image:-webkit-linear-gradient(top,#fdd49a,#fdf59a);background-image:-o-linear-gradient(top,#fdd49a,#fdf59a);background-image:linear-gradient(top,#fdd49a,#fdf59a);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);border-color:#fdf59a #fdf59a #fbed50;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#000}.datepicker table tr td.today.active,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled.disabled,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today.disabled:hover.active,.datepicker table tr td.today.disabled:hover.disabled,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today.disabled:hover:hover,.datepicker table tr td.today.disabled:hover[disabled],.datepicker table tr td.today.disabled[disabled],.datepicker table tr td.today:active,.datepicker table tr td.today:hover,.datepicker table tr td.today:hover.active,.datepicker table tr td.today:hover.disabled,.datepicker table tr td.today:hover:active,.datepicker table tr td.today:hover:hover,.datepicker table tr td.today:hover[disabled],.datepicker table tr td.today[disabled]{background-color:#fdf59a}.datepicker table tr td.today.active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:hover.active,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today:active,.datepicker table tr td.today:hover.active,.datepicker table tr td.today:hover:active{background-color:#fbf069 \9}.datepicker table tr td.today:hover:hover{color:#000}.datepicker table tr td.today.active:hover{color:#fff}.datepicker table tr td.range,.datepicker table tr td.range.disabled,.datepicker table tr td.range.disabled:hover,.datepicker table tr td.range:hover{background:#eee;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.datepicker table tr td.range.today{background-color:#f3d17a}.datepicker table tr td.range.today,.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today:hover{background-image:-moz-linear-gradient(top,#f3c17a,#f3e97a);background-image:-ms-linear-gradient(top,#f3c17a,#f3e97a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f3c17a),to(#f3e97a));background-image:-webkit-linear-gradient(top,#f3c17a,#f3e97a);background-image:-o-linear-gradient(top,#f3c17a,#f3e97a);background-image:linear-gradient(top,#f3c17a,#f3e97a);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);border-color:#f3e97a #f3e97a #edde34;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.datepicker table tr td.range.today.active,.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled.disabled,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today.disabled:hover.active,.datepicker table tr td.range.today.disabled:hover.disabled,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today.disabled:hover:hover,.datepicker table tr td.range.today.disabled:hover[disabled],.datepicker table tr td.range.today.disabled[disabled],.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:hover,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today:hover.disabled,.datepicker table tr td.range.today:hover:active,.datepicker table tr td.range.today:hover:hover,.datepicker table tr td.range.today:hover[disabled],.datepicker table tr td.range.today[disabled]{background-color:#f3e97a}.datepicker table tr td.range.today.active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:hover.active,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today:hover:active{background-color:#efe24b \9}.datepicker table tr td.selected{background-color:#9e9e9e}.datepicker table tr td.selected,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected:hover{background-image:-moz-linear-gradient(top,#b3b3b3,gray);background-image:-ms-linear-gradient(top,#b3b3b3,gray);background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3b3b3),to(gray));background-image:-webkit-linear-gradient(top,#b3b3b3,gray);background-image:-o-linear-gradient(top,#b3b3b3,gray);background-image:linear-gradient(top,#b3b3b3,gray);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);border-color:gray gray #595959;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.selected.active,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled.disabled,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.disabled:hover.active,.datepicker table tr td.selected.disabled:hover.disabled,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected.disabled:hover:hover,.datepicker table tr td.selected.disabled:hover[disabled],.datepicker table tr td.selected.disabled[disabled],.datepicker table tr td.selected:active,.datepicker table tr td.selected:hover,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected:hover.disabled,.datepicker table tr td.selected:hover:active,.datepicker table tr td.selected:hover:hover,.datepicker table tr td.selected:hover[disabled],.datepicker table tr td.selected[disabled]{background-color:gray}.datepicker table tr td.selected.active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:hover.active,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected:active,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected:hover:active{background-color:#666 \9}.datepicker table tr td.active{background-color:#006dcc}.datepicker table tr td.active,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active:hover{background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(top,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.active.active,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled.disabled,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.disabled:hover.active,.datepicker table tr td.active.disabled:hover.disabled,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active.disabled:hover:hover,.datepicker table tr td.active.disabled:hover[disabled],.datepicker table tr td.active.disabled[disabled],.datepicker table tr td.active:active,.datepicker table tr td.active:hover,.datepicker table tr td.active:hover.active,.datepicker table tr td.active:hover.disabled,.datepicker table tr td.active:hover:active,.datepicker table tr td.active:hover:hover,.datepicker table tr td.active:hover[disabled],.datepicker table tr td.active[disabled]{background-color:#04c}.datepicker table tr td.active.active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:hover.active,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active:active,.datepicker table tr td.active:hover.active,.datepicker table tr td.active:hover:active{background-color:#039 \9}.datepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer}.datepicker table tr td span:hover{background:#eee}.datepicker table tr td span.disabled,.datepicker table tr td span.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td span.active{background-color:#006dcc}.datepicker table tr td span.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover{background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(top,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled.disabled,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover.disabled,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active.disabled:hover[disabled],.datepicker table tr td span.active.disabled[disabled],.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover.disabled,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active:hover:hover,.datepicker table tr td span.active:hover[disabled],.datepicker table tr td span.active[disabled]{background-color:#04c}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover:active{background-color:#039 \9}.datepicker table tr td span.new,.datepicker table tr td span.old{color:#999}.datepicker th.datepicker-switch{width:145px}.datepicker tfoot tr th,.datepicker thead tr:first-child th{cursor:pointer}.datepicker tfoot tr th:hover,.datepicker thead tr:first-child th:hover{background:#eee}.datepicker .cw{font-size:10px;width:12px;padding:0 2px 0 5px;vertical-align:middle}.datepicker thead tr:first-child th.cw{cursor:default;background-color:transparent}.input-append.date .add-on i,.input-prepend.date .add-on i{display:block;cursor:pointer;width:16px;height:16px}.input-daterange input{text-align:center}.input-daterange input:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-daterange input:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-daterange .add-on{display:inline-block;width:auto;min-width:16px;height:18px;padding:4px 5px;font-weight:400;line-height:18px;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:1px solid #ccc;margin-left:-5px;margin-right:-5px} \ No newline at end of file diff --git a/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/js/bootstrap-editable.js b/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/js/bootstrap-editable.js deleted file mode 100644 index b78c9f7b..00000000 --- a/aasrp/static/aasrp/libs/x-editable/1.5.3/bootstrap3-editable/js/bootstrap-editable.js +++ /dev/null @@ -1,6883 +0,0 @@ -/*! X-editable - v1.5.3 -* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery -* http://github.com/vitalets/x-editable -* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */ -/** - Form with single input element, two buttons and two states: normal/loading. - Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown. - Editableform is linked with one of input types, e.g. 'text', 'select' etc. - - @class editableform - @uses text - @uses textarea - **/ -(function ($) { - "use strict"; - - var EditableForm = function (div, options) { - this.options = $.extend({}, $.fn.editableform.defaults, options); - this.$div = $(div); //div, containing form. Not form tag. Not editable-element. - if(!this.options.scope) { - this.options.scope = this; - } - //nothing shown after init - }; - - EditableForm.prototype = { - constructor: EditableForm, - initInput: function() { //called once - //take input from options (as it is created in editable-element) - this.input = this.options.input; - - //set initial value - //todo: may be add check: typeof str === 'string' ? - this.value = this.input.str2value(this.options.value); - - //prerender: get input.$input - this.input.prerender(); - }, - initTemplate: function() { - this.$form = $($.fn.editableform.template); - }, - initButtons: function() { - var $btn = this.$form.find('.editable-buttons'); - $btn.append($.fn.editableform.buttons); - if(this.options.showbuttons === 'bottom') { - $btn.addClass('editable-buttons-bottom'); - } - }, - /** - Renders editableform - - @method render - **/ - render: function() { - //init loader - this.$loading = $($.fn.editableform.loading); - this.$div.empty().append(this.$loading); - - //init form template and buttons - this.initTemplate(); - if(this.options.showbuttons) { - this.initButtons(); - } else { - this.$form.find('.editable-buttons').remove(); - } - - //show loading state - this.showLoading(); - - //flag showing is form now saving value to server. - //It is needed to wait when closing form. - this.isSaving = false; - - /** - Fired when rendering starts - @event rendering - @param {Object} event event object - **/ - this.$div.triggerHandler('rendering'); - - //init input - this.initInput(); - - //append input to form - this.$form.find('div.editable-input').append(this.input.$tpl); - - //append form to container - this.$div.append(this.$form); - - //render input - $.when(this.input.render()) - .then($.proxy(function () { - //setup input to submit automatically when no buttons shown - if(!this.options.showbuttons) { - this.input.autosubmit(); - } - - //attach 'cancel' handler - this.$form.find('.editable-cancel').click($.proxy(this.cancel, this)); - - if(this.input.error) { - this.error(this.input.error); - this.$form.find('.editable-submit').attr('disabled', true); - this.input.$input.attr('disabled', true); - //prevent form from submitting - this.$form.submit(function(e){ e.preventDefault(); }); - } else { - this.error(false); - this.input.$input.removeAttr('disabled'); - this.$form.find('.editable-submit').removeAttr('disabled'); - var value = (this.value === null || this.value === undefined || this.value === '') ? this.options.defaultValue : this.value; - this.input.value2input(value); - //attach submit handler - this.$form.submit($.proxy(this.submit, this)); - } - - /** - Fired when form is rendered - @event rendered - @param {Object} event event object - **/ - this.$div.triggerHandler('rendered'); - - this.showForm(); - - //call postrender method to perform actions required visibility of form - if(this.input.postrender) { - this.input.postrender(); - } - }, this)); - }, - cancel: function() { - /** - Fired when form was cancelled by user - @event cancel - @param {Object} event event object - **/ - this.$div.triggerHandler('cancel'); - }, - showLoading: function() { - var w, h; - if(this.$form) { - //set loading size equal to form - w = this.$form.outerWidth(); - h = this.$form.outerHeight(); - if(w) { - this.$loading.width(w); - } - if(h) { - this.$loading.height(h); - } - this.$form.hide(); - } else { - //stretch loading to fill container width - w = this.$loading.parent().width(); - if(w) { - this.$loading.width(w); - } - } - this.$loading.show(); - }, - - showForm: function(activate) { - this.$loading.hide(); - this.$form.show(); - if(activate !== false) { - this.input.activate(); - } - /** - Fired when form is shown - @event show - @param {Object} event event object - **/ - this.$div.triggerHandler('show'); - }, - - error: function(msg) { - var $group = this.$form.find('.control-group'), - $block = this.$form.find('.editable-error-block'), - lines; - - if(msg === false) { - $group.removeClass($.fn.editableform.errorGroupClass); - $block.removeClass($.fn.editableform.errorBlockClass).empty().hide(); - } else { - //convert newline to
for more pretty error display - if(msg) { - lines = (''+msg).split('\n'); - for (var i = 0; i < lines.length; i++) { - lines[i] = $('
').text(lines[i]).html(); - } - msg = lines.join('
'); - } - $group.addClass($.fn.editableform.errorGroupClass); - $block.addClass($.fn.editableform.errorBlockClass).html(msg).show(); - } - }, - - submit: function(e) { - e.stopPropagation(); - e.preventDefault(); - - //get new value from input - var newValue = this.input.input2value(); - - //validation: if validate returns string or truthy value - means error - //if returns object like {newValue: '...'} => submitted value is reassigned to it - var error = this.validate(newValue); - if ($.type(error) === 'object' && error.newValue !== undefined) { - newValue = error.newValue; - this.input.value2input(newValue); - if(typeof error.msg === 'string') { - this.error(error.msg); - this.showForm(); - return; - } - } else if (error) { - this.error(error); - this.showForm(); - return; - } - - //if value not changed --> trigger 'nochange' event and return - /*jslint eqeq: true*/ - if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) { - /*jslint eqeq: false*/ - /** - Fired when value not changed but form is submitted. Requires savenochange = false. - @event nochange - @param {Object} event event object - **/ - this.$div.triggerHandler('nochange'); - return; - } - - //convert value for submitting to server - var submitValue = this.input.value2submit(newValue); - - this.isSaving = true; - - //sending data to server - $.when(this.save(submitValue)) - .done($.proxy(function(response) { - this.isSaving = false; - - //run success callback - var res = typeof this.options.success === 'function' ? this.options.success.call(this.options.scope, response, newValue) : null; - - //if success callback returns false --> keep form open and do not activate input - if(res === false) { - this.error(false); - this.showForm(false); - return; - } - - //if success callback returns string --> keep form open, show error and activate input - if(typeof res === 'string') { - this.error(res); - this.showForm(); - return; - } - - //if success callback returns object like {newValue: } --> use that value instead of submitted - //it is useful if you want to chnage value in url-function - if(res && typeof res === 'object' && res.hasOwnProperty('newValue')) { - newValue = res.newValue; - } - - //clear error message - this.error(false); - this.value = newValue; - /** - Fired when form is submitted - @event save - @param {Object} event event object - @param {Object} params additional params - @param {mixed} params.newValue raw new value - @param {mixed} params.submitValue submitted value as string - @param {Object} params.response ajax response - - @example - $('#form-div').on('save'), function(e, params){ - if(params.newValue === 'username') {...} - }); - **/ - this.$div.triggerHandler('save', {newValue: newValue, submitValue: submitValue, response: response}); - }, this)) - .fail($.proxy(function(xhr) { - this.isSaving = false; - - var msg; - if(typeof this.options.error === 'function') { - msg = this.options.error.call(this.options.scope, xhr, newValue); - } else { - msg = typeof xhr === 'string' ? xhr : xhr.responseText || xhr.statusText || 'Unknown error!'; - } - - this.error(msg); - this.showForm(); - }, this)); - }, - - save: function(submitValue) { - //try parse composite pk defined as json string in data-pk - this.options.pk = $.fn.editableutils.tryParseJson(this.options.pk, true); - - var pk = (typeof this.options.pk === 'function') ? this.options.pk.call(this.options.scope) : this.options.pk, - /* - send on server in following cases: - 1. url is function - 2. url is string AND (pk defined OR send option = always) - */ - send = !!(typeof this.options.url === 'function' || (this.options.url && ((this.options.send === 'always') || (this.options.send === 'auto' && pk !== null && pk !== undefined)))), - params; - - if (send) { //send to server - this.showLoading(); - - //standard params - params = { - name: this.options.name || '', - value: submitValue, - pk: pk - }; - - //additional params - if(typeof this.options.params === 'function') { - params = this.options.params.call(this.options.scope, params); - } else { - //try parse json in single quotes (from data-params attribute) - this.options.params = $.fn.editableutils.tryParseJson(this.options.params, true); - $.extend(params, this.options.params); - } - - if(typeof this.options.url === 'function') { //user's function - return this.options.url.call(this.options.scope, params); - } else { - //send ajax to server and return deferred object - return $.ajax($.extend({ - url : this.options.url, - data : params, - type : 'POST' - }, this.options.ajaxOptions)); - } - } - }, - - validate: function (value) { - if (value === undefined) { - value = this.value; - } - if (typeof this.options.validate === 'function') { - return this.options.validate.call(this.options.scope, value); - } - }, - - option: function(key, value) { - if(key in this.options) { - this.options[key] = value; - } - - if(key === 'value') { - this.setValue(value); - } - - //do not pass option to input as it is passed in editable-element - }, - - setValue: function(value, convertStr) { - if(convertStr) { - this.value = this.input.str2value(value); - } else { - this.value = value; - } - - //if form is visible, update input - if(this.$form && this.$form.is(':visible')) { - this.input.value2input(this.value); - } - } - }; - - /* - Initialize editableform. Applied to jQuery object. - - @method $().editableform(options) - @params {Object} options - @example - var $form = $('<div>').editableform({ - type: 'text', - name: 'username', - url: '/post', - value: 'vitaliy' - }); - - //to display form you should call 'render' method - $form.editableform('render'); - */ - $.fn.editableform = function (option) { - var args = arguments; - return this.each(function () { - var $this = $(this), - data = $this.data('editableform'), - options = typeof option === 'object' && option; - if (!data) { - $this.data('editableform', (data = new EditableForm(this, options))); - } - - if (typeof option === 'string') { //call method - data[option].apply(data, Array.prototype.slice.call(args, 1)); - } - }); - }; - - //keep link to constructor to allow inheritance - $.fn.editableform.Constructor = EditableForm; - - //defaults - $.fn.editableform.defaults = { - /* see also defaults for input */ - - /** - Type of input. Can be text|textarea|select|date|checklist - - @property type - @type string - @default 'text' - **/ - type: 'text', - /** - Url for submit, e.g. '/post' - If function - it will be called instead of ajax. Function should return deferred object to run fail/done callbacks. - - @property url - @type string|function - @default null - @example - url: function(params) { - var d = new $.Deferred; - if(params.value === 'abc') { - return d.reject('error message'); //returning error via deferred object - } else { - //async saving data in js model - someModel.asyncSaveMethod({ - ..., - success: function(){ - d.resolve(); - } - }); - return d.promise(); - } - } - **/ - url:null, - /** - Additional params for submit. If defined as object - it is **appended** to original ajax data (pk, name and value). - If defined as function - returned object **overwrites** original ajax data. - @example - params: function(params) { - //originally params contain pk, name and value - params.a = 1; - return params; - } - - @property params - @type object|function - @default null - **/ - params:null, - /** - Name of field. Will be submitted on server. Can be taken from id attribute - - @property name - @type string - @default null - **/ - name: null, - /** - Primary key of editable object (e.g. record id in database). For composite keys use object, e.g. {id: 1, lang: 'en'}. - Can be calculated dynamically via function. - - @property pk - @type string|object|function - @default null - **/ - pk: null, - /** - Initial value. If not defined - will be taken from element's content. - For __select__ type should be defined (as it is ID of shown text). - - @property value - @type string|object - @default null - **/ - value: null, - /** - Value that will be displayed in input if original field value is empty (`null|undefined|''`). - - @property defaultValue - @type string|object - @default null - @since 1.4.6 - **/ - defaultValue: null, - /** - Strategy for sending data on server. Can be `auto|always|never`. - When 'auto' data will be sent on server **only if pk and url defined**, otherwise new value will be stored locally. - - @property send - @type string - @default 'auto' - **/ - send: 'auto', - /** - Function for client-side validation. If returns string - means validation not passed and string showed as error. - Since 1.5.1 you can modify submitted value by returning object from `validate`: - `{newValue: '...'}` or `{newValue: '...', msg: '...'}` - - @property validate - @type function - @default null - @example - validate: function(value) { - if($.trim(value) == '') { - return 'This field is required'; - } - } - **/ - validate: null, - /** - Success callback. Called when value successfully sent on server and **response status = 200**. - Usefull to work with json response. For example, if your backend response can be {success: true} - or `{success: false, msg: "server error"}` you can check it inside this callback. - If it returns **string** - means error occured and string is shown as error message. - If it returns **object like** `{newValue: <something>}` - it overwrites value, submitted by user - (useful when server changes value). - Otherwise newValue simply rendered into element. - - @property success - @type function - @default null - @example - success: function(response, newValue) { - if(!response.success) return response.msg; - } - **/ - success: null, - /** - Error callback. Called when request failed (response status != 200). - Usefull when you want to parse error response and display a custom message. - Must return **string** - the message to be displayed in the error block. - - @property error - @type function - @default null - @since 1.4.4 - @example - error: function(response, newValue) { - if(response.status === 500) { - return 'Service unavailable. Please try later.'; - } else { - return response.responseText; - } - } - **/ - error: null, - /** - Additional options for submit ajax request. - List of values: http://api.jquery.com/jQuery.ajax - - @property ajaxOptions - @type object - @default null - @since 1.1.1 - @example - ajaxOptions: { - type: 'put', - dataType: 'json' - } - **/ - ajaxOptions: null, - /** - Where to show buttons: left(true)|bottom|false - Form without buttons is auto-submitted. - - @property showbuttons - @type boolean|string - @default true - @since 1.1.1 - **/ - showbuttons: true, - /** - Scope for callback methods (success, validate). - If null means editableform instance itself. - - @property scope - @type DOMElement|object - @default null - @since 1.2.0 - @private - **/ - scope: null, - /** - Whether to save or cancel value when it was not changed but form was submitted - - @property savenochange - @type boolean - @default false - @since 1.2.0 - **/ - savenochange: false - }; - - /* - Note: following params could redefined in engine: bootstrap or jqueryui: - Classes 'control-group' and 'editable-error-block' must always present! - */ - $.fn.editableform.template = '
'+ - '
' + - '
'+ - '
' + - '
' + - '
'; - - //loading div - $.fn.editableform.loading = '
'; - - //buttons - $.fn.editableform.buttons = ''+ - ''; - - //error class attached to control-group - $.fn.editableform.errorGroupClass = null; - - //error class attached to editable-error-block - $.fn.editableform.errorBlockClass = 'editable-error'; - - //engine - $.fn.editableform.engine = 'jquery'; -}(window.jQuery)); - -/** - * EditableForm utilites - */ -(function ($) { - "use strict"; - - //utils - $.fn.editableutils = { - /** - * classic JS inheritance function - */ - inherit: function (Child, Parent) { - var F = function() { }; - F.prototype = Parent.prototype; - Child.prototype = new F(); - Child.prototype.constructor = Child; - Child.superclass = Parent.prototype; - }, - - /** - * set caret position in input - * see http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area - */ - setCursorPosition: function(elem, pos) { - // see: https://github.com/vitalets/x-editable/issues/939 - if (elem.setSelectionRange && /text|search|password|tel|url/i.test(elem.type)) { - try { elem.setSelectionRange(pos, pos); } catch (e) {} - } else if (elem.createTextRange) { - var range = elem.createTextRange(); - range.collapse(true); - range.moveEnd('character', pos); - range.moveStart('character', pos); - range.select(); - } - }, - - /** - * function to parse JSON in *single* quotes. (jquery automatically parse only double quotes) - * That allows such code as: - * safe = true --> means no exception will be thrown - * for details see http://stackoverflow.com/questions/7410348/how-to-set-json-format-to-html5-data-attributes-in-the-jquery - */ - tryParseJson: function(s, safe) { - if (typeof s === 'string' && s.length && s.match(/^[\{\[].*[\}\]]$/)) { - if (safe) { - try { - /*jslint evil: true*/ - s = (new Function('return ' + s))(); - /*jslint evil: false*/ - } catch (e) {} finally { - return s; - } - } else { - /*jslint evil: true*/ - s = (new Function('return ' + s))(); - /*jslint evil: false*/ - } - } - return s; - }, - - /** - * slice object by specified keys - */ - sliceObj: function(obj, keys, caseSensitive /* default: false */) { - var key, keyLower, newObj = {}; - - if (!$.isArray(keys) || !keys.length) { - return newObj; - } - - for (var i = 0; i < keys.length; i++) { - key = keys[i]; - if (obj.hasOwnProperty(key)) { - newObj[key] = obj[key]; - } - - if(caseSensitive === true) { - continue; - } - - //when getting data-* attributes via $.data() it's converted to lowercase. - //details: http://stackoverflow.com/questions/7602565/using-data-attributes-with-jquery - //workaround is code below. - keyLower = key.toLowerCase(); - if (obj.hasOwnProperty(keyLower)) { - newObj[key] = obj[keyLower]; - } - } - - return newObj; - }, - - /* - exclude complex objects from $.data() before pass to config - */ - getConfigData: function($element) { - var data = {}; - $.each($element[0].dataset, function(k, v) { - if(typeof v !== 'object' || (v && typeof v === 'object' && (v.constructor === Object || v.constructor === Array))) { - data[k] = v; - } - }); - return data; - }, - - /* - returns keys of object - */ - objectKeys: function(o) { - if (Object.keys) { - return Object.keys(o); - } else { - if (o !== Object(o)) { - throw new TypeError('Object.keys called on a non-object'); - } - var k=[], p; - for (p in o) { - if (Object.prototype.hasOwnProperty.call(o,p)) { - k.push(p); - } - } - return k; - } - - }, - - /** - method to escape html. - **/ - escape: function(str) { - return $('
').text(str).html(); - }, - - /* - returns array items from sourceData having value property equal or inArray of 'value' - */ - itemsByValue: function(value, sourceData, valueProp) { - if(!sourceData || value === null) { - return []; - } - - if (typeof(valueProp) !== "function") { - var idKey = valueProp || 'value'; - valueProp = function (e) { return e[idKey]; }; - } - - var isValArray = $.isArray(value), - result = [], - that = this; - - $.each(sourceData, function(i, o) { - if(o.children) { - result = result.concat(that.itemsByValue(value, o.children, valueProp)); - } else { - /*jslint eqeq: true*/ - if(isValArray) { - if($.grep(value, function(v){ return v == (o && typeof o === 'object' ? valueProp(o) : o); }).length) { - result.push(o); - } - } else { - var itemValue = (o && (typeof o === 'object')) ? valueProp(o) : o; - if(value == itemValue) { - result.push(o); - } - } - /*jslint eqeq: false*/ - } - }); - - return result; - }, - - /* - Returns input by options: type, mode. - */ - createInput: function(options) { - var TypeConstructor, typeOptions, input, - type = options.type; - - //`date` is some kind of virtual type that is transformed to one of exact types - //depending on mode and core lib - if(type === 'date') { - //inline - if(options.mode === 'inline') { - if($.fn.editabletypes.datefield) { - type = 'datefield'; - } else if($.fn.editabletypes.dateuifield) { - type = 'dateuifield'; - } - //popup - } else { - if($.fn.editabletypes.date) { - type = 'date'; - } else if($.fn.editabletypes.dateui) { - type = 'dateui'; - } - } - - //if type still `date` and not exist in types, replace with `combodate` that is base input - if(type === 'date' && !$.fn.editabletypes.date) { - type = 'combodate'; - } - } - - //`datetime` should be datetimefield in 'inline' mode - if(type === 'datetime' && options.mode === 'inline') { - type = 'datetimefield'; - } - - //change wysihtml5 to textarea for jquery UI and plain versions - if(type === 'wysihtml5' && !$.fn.editabletypes[type]) { - type = 'textarea'; - } - - //create input of specified type. Input will be used for converting value, not in form - if(typeof $.fn.editabletypes[type] === 'function') { - TypeConstructor = $.fn.editabletypes[type]; - typeOptions = this.sliceObj(options, this.objectKeys(TypeConstructor.defaults)); - input = new TypeConstructor(typeOptions); - return input; - } else { - $.error('Unknown type: '+ type); - return false; - } - }, - - //see http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr - supportsTransitions: function () { - var b = document.body || document.documentElement, - s = b.style, - p = 'transition', - v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms']; - - if(typeof s[p] === 'string') { - return true; - } - - // Tests for vendor specific prop - p = p.charAt(0).toUpperCase() + p.substr(1); - for(var i=0; i - This method applied internally in $().editable(). You should subscribe on it's events (save / cancel) to get profit of it.
- Final realization can be different: bootstrap-popover, jqueryui-tooltip, poshytip, inline-div. It depends on which js file you include.
- Applied as jQuery method. - - @class editableContainer - @uses editableform - **/ -(function ($) { - "use strict"; - - var Popup = function (element, options) { - this.init(element, options); - }; - - var Inline = function (element, options) { - this.init(element, options); - }; - - //methods - Popup.prototype = { - containerName: null, //method to call container on element - containerDataName: null, //object name in element's .data() - innerCss: null, //tbd in child class - containerClass: 'editable-container editable-popup', //css class applied to container element - defaults: {}, //container itself defaults - - init: function(element, options) { - this.$element = $(element); - //since 1.4.1 container do not use data-* directly as they already merged into options. - this.options = $.extend({}, $.fn.editableContainer.defaults, options); - this.splitOptions(); - - //set scope of form callbacks to element - this.formOptions.scope = this.$element[0]; - - this.initContainer(); - - //flag to hide container, when saving value will finish - this.delayedHide = false; - - //bind 'destroyed' listener to destroy container when element is removed from dom - this.$element.on('destroyed', $.proxy(function(){ - this.destroy(); - }, this)); - - //attach document handler to close containers on click / escape - if(!$(document).data('editable-handlers-attached')) { - //close all on escape - $(document).on('keyup.editable', function (e) { - if (e.which === 27) { - $('.editable-open').editableContainer('hide', 'cancel'); - //todo: return focus on element - } - }); - - //close containers when click outside - //(mousedown could be better than click, it closes everything also on drag drop) - $(document).on('click.editable', function(e) { - var $target = $(e.target), i, - exclude_classes = ['.editable-container', - '.ui-datepicker-header', - '.datepicker', //in inline mode datepicker is rendered into body - '.modal-backdrop', - '.bootstrap-wysihtml5-insert-image-modal', - '.bootstrap-wysihtml5-insert-link-modal' - ]; - - // select2 has extra body click in IE - // see: https://github.com/ivaynberg/select2/issues/1058 - if ($('.select2-drop-mask').is(':visible')) { - return; - } - - //check if element is detached. It occurs when clicking in bootstrap datepicker - if (!$.contains(document.documentElement, e.target)) { - return; - } - - //for some reason FF 20 generates extra event (click) in select2 widget with e.target = document - //we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199 - //Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec - if($target.is(document)) { - return; - } - - //if click inside one of exclude classes --> no nothing - for(i=0; i container changes size before hide. - */ - - //if form already exist - delete previous data - if(this.$form) { - //todo: destroy prev data! - //this.$form.destroy(); - } - - this.$form = $('
'); - - //insert form into container body - if(this.tip().is(this.innerCss)) { - //for inline container - this.tip().append(this.$form); - } else { - this.tip().find(this.innerCss).append(this.$form); - } - - //render form - this.renderForm(); - }, - - /** - Hides container with form - @method hide() - @param {string} reason Reason caused hiding. Can be save|cancel|onblur|nochange|undefined (=manual) - **/ - hide: function(reason) { - if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) { - return; - } - - //if form is saving value, schedule hide - if(this.$form.data('editableform').isSaving) { - this.delayedHide = {reason: reason}; - return; - } else { - this.delayedHide = false; - } - - this.$element.removeClass('editable-open'); - this.innerHide(); - - /** - Fired when container was hidden. It occurs on both save or cancel. - **Note:** Bootstrap popover has own `hidden` event that now cannot be separated from x-editable's one. - The workaround is to check `arguments.length` that is always `2` for x-editable. - - @event hidden - @param {object} event event object - @param {string} reason Reason caused hiding. Can be save|cancel|onblur|nochange|manual - @example - $('#username').on('hidden', function(e, reason) { - if(reason === 'save' || reason === 'cancel') { - //auto-open next editable - $(this).closest('tr').next().find('.editable').editable('show'); - } - }); - **/ - this.$element.triggerHandler('hidden', reason || 'manual'); - }, - - /* internal show method. To be overwritten in child classes */ - innerShow: function () { - - }, - - /* internal hide method. To be overwritten in child classes */ - innerHide: function () { - - }, - - /** - Toggles container visibility (show / hide) - @method toggle() - @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true. - **/ - toggle: function(closeAll) { - if(this.container() && this.tip() && this.tip().is(':visible')) { - this.hide(); - } else { - this.show(closeAll); - } - }, - - /* - Updates the position of container when content changed. - @method setPosition() - */ - setPosition: function() { - //tbd in child class - }, - - save: function(e, params) { - /** - Fired when new value was submitted. You can use $(this).data('editableContainer') inside handler to access to editableContainer instance - - @event save - @param {Object} event event object - @param {Object} params additional params - @param {mixed} params.newValue submitted value - @param {Object} params.response ajax response - @example - $('#username').on('save', function(e, params) { - //assuming server response: '{success: true}' - var pk = $(this).data('editableContainer').options.pk; - if(params.response && params.response.success) { - alert('value: ' + params.newValue + ' with pk: ' + pk + ' saved!'); - } else { - alert('error!'); - } - }); - **/ - this.$element.triggerHandler('save', params); - - //hide must be after trigger, as saving value may require methods of plugin, applied to input - this.hide('save'); - }, - - /** - Sets new option - - @method option(key, value) - @param {string} key - @param {mixed} value - **/ - option: function(key, value) { - this.options[key] = value; - if(key in this.containerOptions) { - this.containerOptions[key] = value; - this.setContainerOption(key, value); - } else { - this.formOptions[key] = value; - if(this.$form) { - this.$form.editableform('option', key, value); - } - } - }, - - setContainerOption: function(key, value) { - this.call('option', key, value); - }, - - /** - Destroys the container instance - @method destroy() - **/ - destroy: function() { - this.hide(); - this.innerDestroy(); - this.$element.off('destroyed'); - this.$element.removeData('editableContainer'); - }, - - /* to be overwritten in child classes */ - innerDestroy: function() { - - }, - - /* - Closes other containers except one related to passed element. - Other containers can be cancelled or submitted (depends on onblur option) - */ - closeOthers: function(element) { - $('.editable-open').each(function(i, el){ - //do nothing with passed element and it's children - if(el === element || $(el).find(element).length) { - return; - } - - //otherwise cancel or submit all open containers - var $el = $(el), - ec = $el.data('editableContainer'); - - if(!ec) { - return; - } - - if(ec.options.onblur === 'cancel') { - $el.data('editableContainer').hide('onblur'); - } else if(ec.options.onblur === 'submit') { - $el.data('editableContainer').tip().find('form').submit(); - } - }); - - }, - - /** - Activates input of visible container (e.g. set focus) - @method activate() - **/ - activate: function() { - if(this.tip && this.tip().is(':visible') && this.$form) { - this.$form.data('editableform').input.activate(); - } - } - - }; - - /** - jQuery method to initialize editableContainer. - - @method $().editableContainer(options) - @params {Object} options - @example - $('#edit').editableContainer({ - type: 'text', - url: '/post', - pk: 1, - value: 'hello' - }); - **/ - $.fn.editableContainer = function (option) { - var args = arguments; - return this.each(function () { - var $this = $(this), - dataKey = 'editableContainer', - data = $this.data(dataKey), - options = typeof option === 'object' && option, - Constructor = (options.mode === 'inline') ? Inline : Popup; - - if (!data) { - $this.data(dataKey, (data = new Constructor(this, options))); - } - - if (typeof option === 'string') { //call method - data[option].apply(data, Array.prototype.slice.call(args, 1)); - } - }); - }; - - //store constructors - $.fn.editableContainer.Popup = Popup; - $.fn.editableContainer.Inline = Inline; - - //defaults - $.fn.editableContainer.defaults = { - /** - Initial value of form input - - @property value - @type mixed - @default null - @private - **/ - value: null, - /** - Placement of container relative to element. Can be top|right|bottom|left. Not used for inline container. - - @property placement - @type string - @default 'top' - **/ - placement: 'top', - /** - Whether to hide container on save/cancel. - - @property autohide - @type boolean - @default true - @private - **/ - autohide: true, - /** - Action when user clicks outside the container. Can be cancel|submit|ignore. - Setting ignore allows to have several containers open. - - @property onblur - @type string - @default 'cancel' - @since 1.1.1 - **/ - onblur: 'cancel', - - /** - Animation speed (inline mode only) - @property anim - @type string - @default false - **/ - anim: false, - - /** - Mode of editable, can be `popup` or `inline` - - @property mode - @type string - @default 'popup' - @since 1.4.0 - **/ - mode: 'popup' - }; - - /* - * workaround to have 'destroyed' event to destroy popover when element is destroyed - * see http://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom - */ - jQuery.event.special.destroyed = { - remove: function(o) { - if (o.handler) { - o.handler(); - } - } - }; - -}(window.jQuery)); - -/** - * Editable Inline - * --------------------- - */ -(function ($) { - "use strict"; - - //copy prototype from EditableContainer - //extend methods - $.extend($.fn.editableContainer.Inline.prototype, $.fn.editableContainer.Popup.prototype, { - containerName: 'editableform', - innerCss: '.editable-inline', - containerClass: 'editable-container editable-inline', //css class applied to container element - - initContainer: function(){ - //container is element - this.$tip = $(''); - - //convert anim to miliseconds (int) - if(!this.options.anim) { - this.options.anim = 0; - } - }, - - splitOptions: function() { - //all options are passed to form - this.containerOptions = {}; - this.formOptions = this.options; - }, - - tip: function() { - return this.$tip; - }, - - innerShow: function () { - this.$element.hide(); - this.tip().insertAfter(this.$element).show(); - }, - - innerHide: function () { - this.$tip.hide(this.options.anim, $.proxy(function() { - this.$element.show(); - this.innerDestroy(); - }, this)); - }, - - innerDestroy: function() { - if(this.tip()) { - this.tip().empty().remove(); - } - } - }); - -}(window.jQuery)); -/** - Makes editable any HTML element on the page. Applied as jQuery method. - - @class editable - @uses editableContainer - **/ -(function ($) { - "use strict"; - - var Editable = function (element, options) { - this.$element = $(element); - //data-* has more priority over js options: because dynamically created elements may change data-* - this.options = $.extend({}, $.fn.editable.defaults, options, $.fn.editableutils.getConfigData(this.$element)); - if(this.options.selector) { - this.initLive(); - } else { - this.init(); - } - - //check for transition support - if(this.options.highlight && !$.fn.editableutils.supportsTransitions()) { - this.options.highlight = false; - } - }; - - Editable.prototype = { - constructor: Editable, - init: function () { - var isValueByText = false, - doAutotext, finalize; - - //name - this.options.name = this.options.name || this.$element.attr('id'); - - //create input of specified type. Input needed already here to convert value for initial display (e.g. show text by id for select) - //also we set scope option to have access to element inside input specific callbacks (e. g. source as function) - this.options.scope = this.$element[0]; - this.input = $.fn.editableutils.createInput(this.options); - if(!this.input) { - return; - } - - //set value from settings or by element's text - if (this.options.value === undefined || this.options.value === null) { - this.value = this.input.html2value($.trim(this.$element.html())); - isValueByText = true; - } else { - /* - value can be string when received from 'data-value' attribute - for complext objects value can be set as json string in data-value attribute, - e.g. data-value="{city: 'Moscow', street: 'Lenina'}" - */ - this.options.value = $.fn.editableutils.tryParseJson(this.options.value, true); - if(typeof this.options.value === 'string') { - this.value = this.input.str2value(this.options.value); - } else { - this.value = this.options.value; - } - } - - //add 'editable' class to every editable element - this.$element.addClass('editable'); - - //specifically for "textarea" add class .editable-pre-wrapped to keep linebreaks - if(this.input.type === 'textarea') { - this.$element.addClass('editable-pre-wrapped'); - } - - //attach handler activating editable. In disabled mode it just prevent default action (useful for links) - if(this.options.toggle !== 'manual') { - this.$element.addClass('editable-click'); - this.$element.on(this.options.toggle + '.editable', $.proxy(function(e){ - //prevent following link if editable enabled - if(!this.options.disabled) { - e.preventDefault(); - } - - //stop propagation not required because in document click handler it checks event target - //e.stopPropagation(); - - if(this.options.toggle === 'mouseenter') { - //for hover only show container - this.show(); - } else { - //when toggle='click' we should not close all other containers as they will be closed automatically in document click listener - var closeAll = (this.options.toggle !== 'click'); - this.toggle(closeAll); - } - }, this)); - } else { - this.$element.attr('tabindex', -1); //do not stop focus on element when toggled manually - } - - //if display is function it's far more convinient to have autotext = always to render correctly on init - //see https://github.com/vitalets/x-editable-yii/issues/34 - if(typeof this.options.display === 'function') { - this.options.autotext = 'always'; - } - - //check conditions for autotext: - switch(this.options.autotext) { - case 'always': - doAutotext = true; - break; - case 'auto': - //if element text is empty and value is defined and value not generated by text --> run autotext - doAutotext = !$.trim(this.$element.text()).length && this.value !== null && this.value !== undefined && !isValueByText; - break; - default: - doAutotext = false; - } - - //depending on autotext run render() or just finilize init - $.when(doAutotext ? this.render() : true).then($.proxy(function() { - if(this.options.disabled) { - this.disable(); - } else { - this.enable(); - } - /** - Fired when element was initialized by `$().editable()` method. - Please note that you should setup `init` handler **before** applying `editable`. - - @event init - @param {Object} event event object - @param {Object} editable editable instance (as here it cannot accessed via data('editable')) - @since 1.2.0 - @example - $('#username').on('init', function(e, editable) { - alert('initialized ' + editable.options.name); - }); - $('#username').editable(); - **/ - this.$element.triggerHandler('init', this); - }, this)); - }, - - /* - Initializes parent element for live editables - */ - initLive: function() { - //store selector - var selector = this.options.selector; - //modify options for child elements - this.options.selector = false; - this.options.autotext = 'never'; - //listen toggle events - this.$element.on(this.options.toggle + '.editable', selector, $.proxy(function(e){ - var $target = $(e.target).closest(selector); - if(!$target.data('editable')) { - //if delegated element initially empty, we need to clear it's text (that was manually set to `empty` by user) - //see https://github.com/vitalets/x-editable/issues/137 - if($target.hasClass(this.options.emptyclass)) { - $target.empty(); - } - $target.editable(this.options).trigger(e); - } - }, this)); - }, - - /* - Renders value into element's text. - Can call custom display method from options. - Can return deferred object. - @method render() - @param {mixed} response server response (if exist) to pass into display function - */ - render: function(response) { - //do not display anything - if(this.options.display === false) { - return; - } - - //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded - if(this.input.value2htmlFinal) { - return this.input.value2html(this.value, this.$element[0], this.options.display, response); - //if display method defined --> use it - } else if(typeof this.options.display === 'function') { - return this.options.display.call(this.$element[0], this.value, response); - //else use input's original value2html() method - } else { - return this.input.value2html(this.value, this.$element[0]); - } - }, - - /** - Enables editable - @method enable() - **/ - enable: function() { - this.options.disabled = false; - this.$element.removeClass('editable-disabled'); - this.handleEmpty(this.isEmpty); - if(this.options.toggle !== 'manual') { - if(this.$element.attr('tabindex') === '-1') { - this.$element.removeAttr('tabindex'); - } - } - }, - - /** - Disables editable - @method disable() - **/ - disable: function() { - this.options.disabled = true; - this.hide(); - this.$element.addClass('editable-disabled'); - this.handleEmpty(this.isEmpty); - //do not stop focus on this element - this.$element.attr('tabindex', -1); - }, - - /** - Toggles enabled / disabled state of editable element - @method toggleDisabled() - **/ - toggleDisabled: function() { - if(this.options.disabled) { - this.enable(); - } else { - this.disable(); - } - }, - - /** - Sets new option - - @method option(key, value) - @param {string|object} key option name or object with several options - @param {mixed} value option new value - @example - $('.editable').editable('option', 'pk', 2); - **/ - option: function(key, value) { - //set option(s) by object - if(key && typeof key === 'object') { - $.each(key, $.proxy(function(k, v){ - this.option($.trim(k), v); - }, this)); - return; - } - - //set option by string - this.options[key] = value; - - //disabled - if(key === 'disabled') { - return value ? this.disable() : this.enable(); - } - - //value - if(key === 'value') { - this.setValue(value); - } - - //transfer new option to container! - if(this.container) { - this.container.option(key, value); - } - - //pass option to input directly (as it points to the same in form) - if(this.input.option) { - this.input.option(key, value); - } - - }, - - /* - * set emptytext if element is empty - */ - handleEmpty: function (isEmpty) { - //do not handle empty if we do not display anything - if(this.options.display === false) { - return; - } - - /* - isEmpty may be set directly as param of method. - It is required when we enable/disable field and can't rely on content - as node content is text: "Empty" that is not empty %) - */ - if(isEmpty !== undefined) { - this.isEmpty = isEmpty; - } else { - //detect empty - //for some inputs we need more smart check - //e.g. wysihtml5 may have
,

, - if(typeof(this.input.isEmpty) === 'function') { - this.isEmpty = this.input.isEmpty(this.$element); - } else { - this.isEmpty = $.trim(this.$element.html()) === ''; - } - } - - //emptytext shown only for enabled - if(!this.options.disabled) { - if (this.isEmpty) { - this.$element.html(this.options.emptytext); - if(this.options.emptyclass) { - this.$element.addClass(this.options.emptyclass); - } - } else if(this.options.emptyclass) { - this.$element.removeClass(this.options.emptyclass); - } - } else { - //below required if element disable property was changed - if(this.isEmpty) { - this.$element.empty(); - if(this.options.emptyclass) { - this.$element.removeClass(this.options.emptyclass); - } - } - } - }, - - /** - Shows container with form - @method show() - @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true. - **/ - show: function (closeAll) { - if(this.options.disabled) { - return; - } - - //init editableContainer: popover, tooltip, inline, etc.. - if(!this.container) { - var containerOptions = $.extend({}, this.options, { - value: this.value, - input: this.input //pass input to form (as it is already created) - }); - this.$element.editableContainer(containerOptions); - //listen `save` event - this.$element.on("save.internal", $.proxy(this.save, this)); - this.container = this.$element.data('editableContainer'); - } else if(this.container.tip().is(':visible')) { - return; - } - - //show container - this.container.show(closeAll); - }, - - /** - Hides container with form - @method hide() - **/ - hide: function () { - if(this.container) { - this.container.hide(); - } - }, - - /** - Toggles container visibility (show / hide) - @method toggle() - @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true. - **/ - toggle: function(closeAll) { - if(this.container && this.container.tip().is(':visible')) { - this.hide(); - } else { - this.show(closeAll); - } - }, - - /* - * called when form was submitted - */ - save: function(e, params) { - //mark element with unsaved class if needed - if(this.options.unsavedclass) { - /* - Add unsaved css to element if: - - url is not user's function - - value was not sent to server - - params.response === undefined, that means data was not sent - - value changed - */ - var sent = false; - sent = sent || typeof this.options.url === 'function'; - sent = sent || this.options.display === false; - sent = sent || params.response !== undefined; - sent = sent || (this.options.savenochange && this.input.value2str(this.value) !== this.input.value2str(params.newValue)); - - if(sent) { - this.$element.removeClass(this.options.unsavedclass); - } else { - this.$element.addClass(this.options.unsavedclass); - } - } - - //highlight when saving - if(this.options.highlight) { - var $e = this.$element, - bgColor = $e.css('background-color'); - - $e.css('background-color', this.options.highlight); - setTimeout(function(){ - if(bgColor === 'transparent') { - bgColor = ''; - } - $e.css('background-color', bgColor); - $e.addClass('editable-bg-transition'); - setTimeout(function(){ - $e.removeClass('editable-bg-transition'); - }, 1700); - }, 10); - } - - //set new value - this.setValue(params.newValue, false, params.response); - - /** - Fired when new value was submitted. You can use $(this).data('editable') to access to editable instance - - @event save - @param {Object} event event object - @param {Object} params additional params - @param {mixed} params.newValue submitted value - @param {Object} params.response ajax response - @example - $('#username').on('save', function(e, params) { - alert('Saved value: ' + params.newValue); - }); - **/ - //event itself is triggered by editableContainer. Description here is only for documentation - }, - - validate: function () { - if (typeof this.options.validate === 'function') { - return this.options.validate.call(this, this.value); - } - }, - - /** - Sets new value of editable - @method setValue(value, convertStr) - @param {mixed} value new value - @param {boolean} convertStr whether to convert value from string to internal format - **/ - setValue: function(value, convertStr, response) { - if(convertStr) { - this.value = this.input.str2value(value); - } else { - this.value = value; - } - if(this.container) { - this.container.option('value', this.value); - } - $.when(this.render(response)) - .then($.proxy(function() { - this.handleEmpty(); - }, this)); - }, - - /** - Activates input of visible container (e.g. set focus) - @method activate() - **/ - activate: function() { - if(this.container) { - this.container.activate(); - } - }, - - /** - Removes editable feature from element - @method destroy() - **/ - destroy: function() { - this.disable(); - - if(this.container) { - this.container.destroy(); - } - - this.input.destroy(); - - if(this.options.toggle !== 'manual') { - this.$element.removeClass('editable-click'); - this.$element.off(this.options.toggle + '.editable'); - } - - this.$element.off("save.internal"); - - this.$element.removeClass('editable editable-open editable-disabled'); - this.$element.removeData('editable'); - } - }; - - /* EDITABLE PLUGIN DEFINITION - * ======================= */ - - /** - jQuery method to initialize editable element. - - @method $().editable(options) - @params {Object} options - @example - $('#username').editable({ - type: 'text', - url: '/post', - pk: 1 - }); - **/ - $.fn.editable = function (option) { - //special API methods returning non-jquery object - var result = {}, args = arguments, datakey = 'editable'; - switch (option) { - /** - Runs client-side validation for all matched editables - - @method validate() - @returns {Object} validation errors map - @example - $('#username, #fullname').editable('validate'); - // possible result: - { - username: "username is required", - fullname: "fullname should be minimum 3 letters length" - } - **/ - case 'validate': - this.each(function () { - var $this = $(this), data = $this.data(datakey), error; - if (data && (error = data.validate())) { - result[data.options.name] = error; - } - }); - return result; - - /** - Returns current values of editable elements. - Note that it returns an **object** with name-value pairs, not a value itself. It allows to get data from several elements. - If value of some editable is `null` or `undefined` it is excluded from result object. - When param `isSingle` is set to **true** - it is supposed you have single element and will return value of editable instead of object. - - @method getValue() - @param {bool} isSingle whether to return just value of single element - @returns {Object} object of element names and values - @example - $('#username, #fullname').editable('getValue'); - //result: - { - username: "superuser", - fullname: "John" - } - //isSingle = true - $('#username').editable('getValue', true); - //result "superuser" - **/ - case 'getValue': - if(arguments.length === 2 && arguments[1] === true) { //isSingle = true - result = this.eq(0).data(datakey).value; - } else { - this.each(function () { - var $this = $(this), data = $this.data(datakey); - if (data && data.value !== undefined && data.value !== null) { - result[data.options.name] = data.input.value2submit(data.value); - } - }); - } - return result; - - /** - This method collects values from several editable elements and submit them all to server. - Internally it runs client-side validation for all fields and submits only in case of success. - See
creating new records for details. - Since 1.5.1 `submit` can be applied to single element to send data programmatically. In that case - `url`, `success` and `error` is taken from initial options and you can just call `$('#username').editable('submit')`. - - @method submit(options) - @param {object} options - @param {object} options.url url to submit data - @param {object} options.data additional data to submit - @param {object} options.ajaxOptions additional ajax options - @param {function} options.error(obj) error handler - @param {function} options.success(obj,config) success handler - @returns {Object} jQuery object - **/ - case 'submit': //collects value, validate and submit to server for creating new record - var config = arguments[1] || {}, - $elems = this, - errors = this.editable('validate'); - - // validation ok - if($.isEmptyObject(errors)) { - var ajaxOptions = {}; - - // for single element use url, success etc from options - if($elems.length === 1) { - var editable = $elems.data('editable'); - //standard params - var params = { - name: editable.options.name || '', - value: editable.input.value2submit(editable.value), - pk: (typeof editable.options.pk === 'function') ? - editable.options.pk.call(editable.options.scope) : - editable.options.pk - }; - - //additional params - if(typeof editable.options.params === 'function') { - params = editable.options.params.call(editable.options.scope, params); - } else { - //try parse json in single quotes (from data-params attribute) - editable.options.params = $.fn.editableutils.tryParseJson(editable.options.params, true); - $.extend(params, editable.options.params); - } - - ajaxOptions = { - url: editable.options.url, - data: params, - type: 'POST' - }; - - // use success / error from options - config.success = config.success || editable.options.success; - config.error = config.error || editable.options.error; - - // multiple elements - } else { - var values = this.editable('getValue'); - - ajaxOptions = { - url: config.url, - data: values, - type: 'POST' - }; - } - - // ajax success callabck (response 200 OK) - ajaxOptions.success = typeof config.success === 'function' ? function(response) { - config.success.call($elems, response, config); - } : $.noop; - - // ajax error callabck - ajaxOptions.error = typeof config.error === 'function' ? function() { - config.error.apply($elems, arguments); - } : $.noop; - - // extend ajaxOptions - if(config.ajaxOptions) { - $.extend(ajaxOptions, config.ajaxOptions); - } - - // extra data - if(config.data) { - $.extend(ajaxOptions.data, config.data); - } - - // perform ajax request - $.ajax(ajaxOptions); - } else { //client-side validation error - if(typeof config.error === 'function') { - config.error.call($elems, errors); - } - } - return this; - } - - //return jquery object - return this.each(function () { - var $this = $(this), - data = $this.data(datakey), - options = typeof option === 'object' && option; - - //for delegated targets do not store `editable` object for element - //it's allows several different selectors. - //see: https://github.com/vitalets/x-editable/issues/312 - if(options && options.selector) { - data = new Editable(this, options); - return; - } - - if (!data) { - $this.data(datakey, (data = new Editable(this, options))); - } - - if (typeof option === 'string') { //call method - data[option].apply(data, Array.prototype.slice.call(args, 1)); - } - }); - }; - - - $.fn.editable.defaults = { - /** - Type of input. Can be text|textarea|select|date|checklist and more - - @property type - @type string - @default 'text' - **/ - type: 'text', - /** - Sets disabled state of editable - - @property disabled - @type boolean - @default false - **/ - disabled: false, - /** - How to toggle editable. Can be click|dblclick|mouseenter|manual. - When set to manual you should manually call show/hide methods of editable. - **Note**: if you call show or toggle inside **click** handler of some DOM element, - you need to apply e.stopPropagation() because containers are being closed on any click on document. - - @example - $('#edit-button').click(function(e) { - e.stopPropagation(); - $('#username').editable('toggle'); - }); - - @property toggle - @type string - @default 'click' - **/ - toggle: 'click', - /** - Text shown when element is empty. - - @property emptytext - @type string - @default 'Empty' - **/ - emptytext: 'Empty', - /** - Allows to automatically set element's text based on it's value. Can be auto|always|never. Useful for select and date. - For example, if dropdown list is {1: 'a', 2: 'b'} and element's value set to 1, it's html will be automatically set to 'a'. - auto - text will be automatically set only if element is empty. - always|never - always(never) try to set element's text. - - @property autotext - @type string - @default 'auto' - **/ - autotext: 'auto', - /** - Initial value of input. If not set, taken from element's text. - Note, that if element's text is empty - text is automatically generated from value and can be customized (see `autotext` option). - For example, to display currency sign: - @example - - - - @property value - @type mixed - @default element's text - **/ - value: null, - /** - Callback to perform custom displaying of value in element's text. - If `null`, default input's display used. - If `false`, no displaying methods will be called, element's text will never change. - Runs under element's scope. - _**Parameters:**_ - - * `value` current value to be displayed - * `response` server response (if display called after ajax submit), since 1.4.0 - - For _inputs with source_ (select, checklist) parameters are different: - - * `value` current value to be displayed - * `sourceData` array of items for current input (e.g. dropdown items) - * `response` server response (if display called after ajax submit), since 1.4.0 - - To get currently selected items use `$.fn.editableutils.itemsByValue(value, sourceData)`. - - @property display - @type function|boolean - @default null - @since 1.2.0 - @example - display: function(value, sourceData) { - //display checklist as comma-separated values - var html = [], - checked = $.fn.editableutils.itemsByValue(value, sourceData); - - if(checked.length) { - $.each(checked, function(i, v) { html.push($.fn.editableutils.escape(v.text)); }); - $(this).html(html.join(', ')); - } else { - $(this).empty(); - } - } - **/ - display: null, - /** - Css class applied when editable text is empty. - - @property emptyclass - @type string - @since 1.4.1 - @default editable-empty - **/ - emptyclass: 'editable-empty', - /** - Css class applied when value was stored but not sent to server (`pk` is empty or `send = 'never'`). - You may set it to `null` if you work with editables locally and submit them together. - - @property unsavedclass - @type string - @since 1.4.1 - @default editable-unsaved - **/ - unsavedclass: 'editable-unsaved', - /** - If selector is provided, editable will be delegated to the specified targets. - Usefull for dynamically generated DOM elements. - **Please note**, that delegated targets can't be initialized with `emptytext` and `autotext` options, - as they actually become editable only after first click. - You should manually set class `editable-click` to these elements. - Also, if element originally empty you should add class `editable-empty`, set `data-value=""` and write emptytext into element: - - @property selector - @type string - @since 1.4.1 - @default null - @example -
- - Empty - - Operator -
- - - **/ - selector: null, - /** - Color used to highlight element after update. Implemented via CSS3 transition, works in modern browsers. - - @property highlight - @type string|boolean - @since 1.4.5 - @default #FFFF80 - **/ - highlight: '#FFFF80' - }; - -}(window.jQuery)); - -/** - AbstractInput - base class for all editable inputs. - It defines interface to be implemented by any input type. - To create your own input you can inherit from this class. - - @class abstractinput - **/ -(function ($) { - "use strict"; - - //types - $.fn.editabletypes = {}; - - var AbstractInput = function () { }; - - AbstractInput.prototype = { - /** - Initializes input - - @method init() - **/ - init: function(type, options, defaults) { - this.type = type; - this.options = $.extend({}, defaults, options); - }, - - /* - this method called before render to init $tpl that is inserted in DOM - */ - prerender: function() { - this.$tpl = $(this.options.tpl); //whole tpl as jquery object - this.$input = this.$tpl; //control itself, can be changed in render method - this.$clear = null; //clear button - this.error = null; //error message, if input cannot be rendered - }, - - /** - Renders input from tpl. Can return jQuery deferred object. - Can be overwritten in child objects - - @method render() - **/ - render: function() { - - }, - - /** - Sets element's html by value. - - @method value2html(value, element) - @param {mixed} value - @param {DOMElement} element - **/ - value2html: function(value, element) { - $(element)[this.options.escape ? 'text' : 'html']($.trim(value)); - }, - - /** - Converts element's html to value - - @method html2value(html) - @param {string} html - @returns {mixed} - **/ - html2value: function(html) { - return $('
').html(html).text(); - }, - - /** - Converts value to string (for internal compare). For submitting to server used value2submit(). - - @method value2str(value) - @param {mixed} value - @returns {string} - **/ - value2str: function(value) { - return String(value); - }, - - /** - Converts string received from server into value. Usually from `data-value` attribute. - - @method str2value(str) - @param {string} str - @returns {mixed} - **/ - str2value: function(str) { - return str; - }, - - /** - Converts value for submitting to server. Result can be string or object. - - @method value2submit(value) - @param {mixed} value - @returns {mixed} - **/ - value2submit: function(value) { - return value; - }, - - /** - Sets value of input. - - @method value2input(value) - @param {mixed} value - **/ - value2input: function(value) { - this.$input.val(value); - }, - - /** - Returns value of input. Value can be object (e.g. datepicker) - - @method input2value() - **/ - input2value: function() { - return this.$input.val(); - }, - - /** - Activates input. For text it sets focus. - - @method activate() - **/ - activate: function() { - if(this.$input.is(':visible')) { - this.$input.focus(); - } - }, - - /** - Creates input. - - @method clear() - **/ - clear: function() { - this.$input.val(null); - }, - - /** - method to escape html. - **/ - escape: function(str) { - return $('
').text(str).html(); - }, - - /** - attach handler to automatically submit form when value changed (useful when buttons not shown) - **/ - autosubmit: function() { - - }, - - /** - Additional actions when destroying element - **/ - destroy: function() { - }, - - // -------- helper functions -------- - setClass: function() { - if(this.options.inputclass) { - this.$input.addClass(this.options.inputclass); - } - }, - - setAttr: function(attr) { - if (this.options[attr] !== undefined && this.options[attr] !== null) { - this.$input.attr(attr, this.options[attr]); - } - }, - - option: function(key, value) { - this.options[key] = value; - } - - }; - - AbstractInput.defaults = { - /** - HTML template of input. Normally you should not change it. - - @property tpl - @type string - @default '' - **/ - tpl: '', - /** - CSS class automatically applied to input - - @property inputclass - @type string - @default null - **/ - inputclass: null, - - /** - If `true` - html will be escaped in content of element via $.text() method. - If `false` - html will not be escaped, $.html() used. - When you use own `display` function, this option obviosly has no effect. - - @property escape - @type boolean - @since 1.5.0 - @default true - **/ - escape: true, - - //scope for external methods (e.g. source defined as function) - //for internal use only - scope: null, - - //need to re-declare showbuttons here to get it's value from common config (passed only options existing in defaults) - showbuttons: true - }; - - $.extend($.fn.editabletypes, {abstractinput: AbstractInput}); - -}(window.jQuery)); - -/** - List - abstract class for inputs that have source option loaded from js array or via ajax - - @class list - @extends abstractinput - **/ -(function ($) { - "use strict"; - - var List = function (options) { - - }; - - $.fn.editableutils.inherit(List, $.fn.editabletypes.abstractinput); - - $.extend(List.prototype, { - render: function () { - var deferred = $.Deferred(); - - this.error = null; - this.onSourceReady(function () { - this.renderList(); - deferred.resolve(); - }, function () { - this.error = this.options.sourceError; - deferred.resolve(); - }); - - return deferred.promise(); - }, - - html2value: function (html) { - return null; //can't set value by text - }, - - value2html: function (value, element, display, response) { - var deferred = $.Deferred(), - success = function () { - if(typeof display === 'function') { - //custom display method - display.call(element, value, this.sourceData, response); - } else { - this.value2htmlFinal(value, element); - } - deferred.resolve(); - }; - - //for null value just call success without loading source - if(value === null) { - success.call(this); - } else { - this.onSourceReady(success, function () { deferred.resolve(); }); - } - - return deferred.promise(); - }, - - // ------------- additional functions ------------ - - onSourceReady: function (success, error) { - //run source if it function - var source; - if ($.isFunction(this.options.source)) { - source = this.options.source.call(this.options.scope); - this.sourceData = null; - //note: if function returns the same source as URL - sourceData will be taken from cahce and no extra request performed - } else { - source = this.options.source; - } - - //if allready loaded just call success - if(this.options.sourceCache && $.isArray(this.sourceData)) { - success.call(this); - return; - } - - //try parse json in single quotes (for double quotes jquery does automatically) - try { - source = $.fn.editableutils.tryParseJson(source, false); - } catch (e) { - error.call(this); - return; - } - - //loading from url - if (typeof source === 'string') { - //try to get sourceData from cache - if(this.options.sourceCache) { - var cacheID = source, - cache; - - if (!$(document).data(cacheID)) { - $(document).data(cacheID, {}); - } - cache = $(document).data(cacheID); - - //check for cached data - if (cache.loading === false && cache.sourceData) { //take source from cache - this.sourceData = cache.sourceData; - this.doPrepend(); - success.call(this); - return; - } else if (cache.loading === true) { //cache is loading, put callback in stack to be called later - cache.callbacks.push($.proxy(function () { - this.sourceData = cache.sourceData; - this.doPrepend(); - success.call(this); - }, this)); - - //also collecting error callbacks - cache.err_callbacks.push($.proxy(error, this)); - return; - } else { //no cache yet, activate it - cache.loading = true; - cache.callbacks = []; - cache.err_callbacks = []; - } - } - - //ajaxOptions for source. Can be overwritten bt options.sourceOptions - var ajaxOptions = $.extend({ - url: source, - type: 'get', - cache: false, - dataType: 'json', - success: $.proxy(function (data) { - if(cache) { - cache.loading = false; - } - this.sourceData = this.makeArray(data); - if($.isArray(this.sourceData)) { - if(cache) { - //store result in cache - cache.sourceData = this.sourceData; - //run success callbacks for other fields waiting for this source - $.each(cache.callbacks, function () { this.call(); }); - } - this.doPrepend(); - success.call(this); - } else { - error.call(this); - if(cache) { - //run error callbacks for other fields waiting for this source - $.each(cache.err_callbacks, function () { this.call(); }); - } - } - }, this), - error: $.proxy(function () { - error.call(this); - if(cache) { - cache.loading = false; - //run error callbacks for other fields - $.each(cache.err_callbacks, function () { this.call(); }); - } - }, this) - }, this.options.sourceOptions); - - //loading sourceData from server - $.ajax(ajaxOptions); - - } else { //options as json/array - this.sourceData = this.makeArray(source); - - if($.isArray(this.sourceData)) { - this.doPrepend(); - success.call(this); - } else { - error.call(this); - } - } - }, - - doPrepend: function () { - if(this.options.prepend === null || this.options.prepend === undefined) { - return; - } - - if(!$.isArray(this.prependData)) { - //run prepend if it is function (once) - if ($.isFunction(this.options.prepend)) { - this.options.prepend = this.options.prepend.call(this.options.scope); - } - - //try parse json in single quotes - this.options.prepend = $.fn.editableutils.tryParseJson(this.options.prepend, true); - - //convert prepend from string to object - if (typeof this.options.prepend === 'string') { - this.options.prepend = {'': this.options.prepend}; - } - - this.prependData = this.makeArray(this.options.prepend); - } - - if($.isArray(this.prependData) && $.isArray(this.sourceData)) { - this.sourceData = this.prependData.concat(this.sourceData); - } - }, - - /* - renders input list - */ - renderList: function() { - // this method should be overwritten in child class - }, - - /* - set element's html by value - */ - value2htmlFinal: function(value, element) { - // this method should be overwritten in child class - }, - - /** - * convert data to array suitable for sourceData, e.g. [{value: 1, text: 'abc'}, {...}] - */ - makeArray: function(data) { - var count, obj, result = [], item, iterateItem; - if(!data || typeof data === 'string') { - return null; - } - - if($.isArray(data)) { //array - /* - function to iterate inside item of array if item is object. - Caclulates count of keys in item and store in obj. - */ - iterateItem = function (k, v) { - obj = {value: k, text: v}; - if(count++ >= 2) { - return false;// exit from `each` if item has more than one key. - } - }; - - for(var i = 0; i < data.length; i++) { - item = data[i]; - if(typeof item === 'object') { - count = 0; //count of keys inside item - $.each(item, iterateItem); - //case: [{val1: 'text1'}, {val2: 'text2} ...] - if(count === 1) { - result.push(obj); - //case: [{value: 1, text: 'text1'}, {value: 2, text: 'text2'}, ...] - } else if(count > 1) { - //removed check of existance: item.hasOwnProperty('value') && item.hasOwnProperty('text') - if(item.children) { - item.children = this.makeArray(item.children); - } - result.push(item); - } - } else { - //case: ['text1', 'text2' ...] - result.push({value: item, text: item}); - } - } - } else { //case: {val1: 'text1', val2: 'text2, ...} - $.each(data, function (k, v) { - result.push({value: k, text: v}); - }); - } - return result; - }, - - option: function(key, value) { - this.options[key] = value; - if(key === 'source') { - this.sourceData = null; - } - if(key === 'prepend') { - this.prependData = null; - } - } - - }); - - List.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, { - /** - Source data for list. - If **array** - it should be in format: `[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]` - For compability, object format is also supported: `{"1": "text1", "2": "text2" ...}` but it does not guarantee elements order. - - If **string** - considered ajax url to load items. In that case results will be cached for fields with the same source and name. See also `sourceCache` option. - - If **function**, it should return data in format above (since 1.4.0). - - Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only): - @example - [ - {text: "group1", children: [ - {value: 1, text: "text1"}, - {value: 2, text: "text2"} - ]}, - ... - ] - - - @property source - @type string | array | object | function - @default null - **/ - source: null, - /** - Data automatically prepended to the beginning of dropdown list. - - @property prepend - @type string | array | object | function - @default false - **/ - prepend: false, - /** - Error message when list cannot be loaded (e.g. ajax error) - - @property sourceError - @type string - @default Error when loading list - **/ - sourceError: 'Error when loading list', - /** - if `true` and source is **string url** - results will be cached for fields with the same source. - Usefull for editable column in grid to prevent extra requests. - - @property sourceCache - @type boolean - @default true - @since 1.2.0 - **/ - sourceCache: true, - /** - Additional ajax options to be used in $.ajax() when loading list from server. - Useful to send extra parameters or change request method. - - @property sourceOptions - @type object|function - @default null - @since 1.5.0 - @example - sourceOptions: { - data: {param: 123}, - type: 'post' - } - - **/ - sourceOptions: null - }); - - $.fn.editabletypes.list = List; - -}(window.jQuery)); - -/** - Text input - - @class text - @extends abstractinput - @final - @example - awesome - - **/ -(function ($) { - "use strict"; - - var Text = function (options) { - this.init('text', options, Text.defaults); - }; - - $.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput); - - $.extend(Text.prototype, { - render: function() { - this.renderClear(); - this.setClass(); - this.setAttr('placeholder'); - }, - - activate: function() { - if(this.$input.is(':visible')) { - this.$input.focus(); -// if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"],[type="number"],[type="email"]')) { - if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) { - $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length); - } - - if(this.toggleClear) { - this.toggleClear(); - } - } - }, - - //render clear button - renderClear: function() { - if (this.options.clear) { - this.$clear = $(''); - this.$input.after(this.$clear) - .css('padding-right', 24) - .keyup($.proxy(function(e) { - //arrows, enter, tab, etc - if(~$.inArray(e.keyCode, [40,38,9,13,27])) { - return; - } - - clearTimeout(this.t); - var that = this; - this.t = setTimeout(function() { - that.toggleClear(e); - }, 100); - - }, this)) - .parent().css('position', 'relative'); - - this.$clear.click($.proxy(this.clear, this)); - } - }, - - postrender: function() { - /* - //now `clear` is positioned via css - if(this.$clear) { - //can position clear button only here, when form is shown and height can be calculated -// var h = this.$input.outerHeight(true) || 20, - var h = this.$clear.parent().height(), - delta = (h - this.$clear.height()) / 2; - - //this.$clear.css({bottom: delta, right: delta}); - } - */ - }, - - //show / hide clear button - toggleClear: function(e) { - if(!this.$clear) { - return; - } - - var len = this.$input.val().length, - visible = this.$clear.is(':visible'); - - if(len && !visible) { - this.$clear.show(); - } - - if(!len && visible) { - this.$clear.hide(); - } - }, - - clear: function() { - this.$clear.hide(); - this.$input.val('').focus(); - } - }); - - Text.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, { - /** - @property tpl - @default - **/ - tpl: '', - /** - Placeholder attribute of input. Shown when input is empty. - - @property placeholder - @type string - @default null - **/ - placeholder: null, - - /** - Whether to show `clear` button - - @property clear - @type boolean - @default true - **/ - clear: true - }); - - $.fn.editabletypes.text = Text; - -}(window.jQuery)); - -/** - Textarea input - - @class textarea - @extends abstractinput - @final - @example - awesome comment! - - **/ -(function ($) { - "use strict"; - - var Textarea = function (options) { - this.init('textarea', options, Textarea.defaults); - }; - - $.fn.editableutils.inherit(Textarea, $.fn.editabletypes.abstractinput); - - $.extend(Textarea.prototype, { - render: function () { - this.setClass(); - this.setAttr('placeholder'); - this.setAttr('rows'); - - //ctrl + enter - this.$input.keydown(function (e) { - if (e.ctrlKey && e.which === 13) { - $(this).closest('form').submit(); - } - }); - }, - - //using `white-space: pre-wrap` solves \n <--> BR conversion very elegant! - /* - value2html: function(value, element) { - var html = '', lines; - if(value) { - lines = value.split("\n"); - for (var i = 0; i < lines.length; i++) { - lines[i] = $('
').text(lines[i]).html(); - } - html = lines.join('
'); - } - $(element).html(html); - }, - - html2value: function(html) { - if(!html) { - return ''; - } - - var regex = new RegExp(String.fromCharCode(10), 'g'); - var lines = html.split(//i); - for (var i = 0; i < lines.length; i++) { - var text = $('
').html(lines[i]).text(); - - // Remove newline characters (\n) to avoid them being converted by value2html() method - // thus adding extra
tags - text = text.replace(regex, ''); - - lines[i] = text; - } - return lines.join("\n"); - }, - */ - activate: function() { - $.fn.editabletypes.text.prototype.activate.call(this); - } - }); - - Textarea.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, { - /** - @property tpl - @default - **/ - tpl:'', - /** - @property inputclass - @default input-large - **/ - inputclass: 'input-large', - /** - Placeholder attribute of input. Shown when input is empty. - - @property placeholder - @type string - @default null - **/ - placeholder: null, - /** - Number of rows in textarea - - @property rows - @type integer - @default 7 - **/ - rows: 7 - }); - - $.fn.editabletypes.textarea = Textarea; - -}(window.jQuery)); - -/** - Select (dropdown) - - @class select - @extends list - @final - @example - - - **/ -(function ($) { - "use strict"; - - var Select = function (options) { - this.init('select', options, Select.defaults); - }; - - $.fn.editableutils.inherit(Select, $.fn.editabletypes.list); - - $.extend(Select.prototype, { - renderList: function() { - this.$input.empty(); - var escape = this.options.escape; - - var fillItems = function($el, data) { - var attr; - if($.isArray(data)) { - for(var i=0; i', attr), data[i].children)); - } else { - attr.value = data[i].value; - if(data[i].disabled) { - attr.disabled = true; - } - var $option = $('