templates/bundles/SonataAdminBundle/CRUD/Association/edit_many_script.html.twig line 1

Open in your IDE?
  1. {#
  2. This file is part of the Sonata package.
  3. (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  4. For the full copyright and license information, please view the LICENSE
  5. file that was distributed with this source code.
  6. #}
  7. {#
  8. This code manages the many-to-[one|many] association field popup
  9. #}
  10. {% autoescape false %}
  11.     {% set associationadmin = sonata_admin.field_description.associationadmin %}
  12.     <!-- edit many association -->
  13.     <script type="text/javascript">
  14.         {#
  15.         handle link click in a list :
  16.           - if the parent has an objectId defined then the related input get updated
  17.           - if the parent has NO object then an ajax request is made to refresh the popup
  18.         #}
  19.         var field_dialog_form_list_link_{{ id }} = function(event) {
  20.             initialize_popup_{{ id }}();
  21.             var target = jQuery(this);
  22.             if (target.attr('href').length === 0 || target.attr('href') === '#') {
  23.                 return;
  24.             }
  25.             event.preventDefault();
  26.             event.stopPropagation();
  27.             Admin.log('[{{ id }}|field_dialog_form_list_link] handle link click in a list');
  28.             var element = jQuery(this).parents('#field_dialog_{{ id }} .sonata-ba-list-field');
  29.             // the user does not click on a row column
  30.             if (element.length == 0) {
  31.                 Admin.log('[{{ id }}|field_dialog_form_list_link] the user does not click on a row column, make ajax call to retrieve inner html');
  32.                 // make a recursive call (ie: reset the filter)
  33.                 jQuery.ajax({
  34.                     type: 'GET',
  35.                     url: jQuery(this).attr('href'),
  36.                     dataType: 'html',
  37.                     success: function(html) {
  38.                         Admin.log('[{{ id }}|field_dialog_form_list_link] callback success, attach valid js event');
  39.                         field_dialog_content_{{ id }}.html(html);
  40.                         field_dialog_form_list_handle_action_{{ id }}();
  41.                         Admin.shared_setup(field_dialog_{{ id }});
  42.                     }
  43.                 });
  44.                 return;
  45.             }
  46.             Admin.log('[{{ id }}|field_dialog_form_list_link] the user select one element, update input and hide the modal');
  47.             jQuery('#{{ id }}').val(element.attr('objectId'));
  48.             jQuery('#{{ id }}').trigger('change');
  49.             {# Aquí se verifica los save-field-db y guardarlos en sus input correspondientes #}
  50.             // FIXME hay que pasar un data-class_inputs pasar saber que items cambiar y no cambiar todos los items similares de todo el admin.
  51.             element.parents('tr').find('.save-field-db').each(function (index, value) {
  52.                 reloadModelListType(value);
  53.             });
  54.             field_dialog_{{ id }}.modal('hide');
  55.         };
  56.         // this function handle action on the modal list when inside a selected list
  57.         var field_dialog_form_list_handle_action_{{ id }}  =  function() {
  58.             Admin.log('[{{ id }}|field_dialog_form_list_handle_action] attaching valid js event');
  59.             // capture the submit event to make an ajax call, ie : POST data to the
  60.             // related create admin
  61.             jQuery('a', field_dialog_{{ id }}).on('click', field_dialog_form_list_link_{{ id }});
  62.             jQuery('form', field_dialog_{{ id }}).on('submit', function(event) {
  63.                 event.preventDefault();
  64.                 var form = jQuery(this);
  65.                 Admin.log('[{{ id }}|field_dialog_form_list_handle_action] catching submit event, sending ajax request');
  66.                 jQuery(form).ajaxSubmit({
  67.                     type: form.attr('method'),
  68.                     url: form.attr('action'),
  69.                     dataType: 'html',
  70.                     data: {_xml_http_request: true},
  71.                     success: function(html) {
  72.                         Admin.log('[{{ id }}|field_dialog_form_list_handle_action] form submit success, restoring event');
  73.                         field_dialog_content_{{ id }}.html(html);
  74.                         field_dialog_form_list_handle_action_{{ id }}();
  75.                         Admin.shared_setup(field_dialog_{{ id }});
  76.                         loadNavPrometeo(field_dialog_content_{{ id }});
  77.                     }
  78.                 });
  79.             });
  80.         };
  81.         // handle the list link
  82.         var field_dialog_form_list_{{ id }} = function(event) {
  83.             initialize_popup_{{ id }}();
  84.             event.preventDefault();
  85.             event.stopPropagation();
  86.             Admin.log('[{{ id }}|field_dialog_form_list] open the list modal');
  87.             var a = jQuery(this);
  88.             field_dialog_content_{{ id }}.html('');
  89.             // retrieve the form element from the related admin generator
  90.             jQuery.ajax({
  91.                 url: a.attr('href'),
  92.                 dataType: 'html',
  93.                 success: function(html) {
  94.                     Admin.log('[{{ id }}|field_dialog_form_list] retrieving the list content');
  95.                     // populate the popup container
  96.                     field_dialog_content_{{ id }}.html(html);
  97.                     {% if associationadmin.label is not empty %}
  98.                     field_dialog_title_{{ id }}.html("{{ associationadmin.label|trans({}, associationadmin.translationdomain) }}");
  99.                     {% endif %}
  100.                     Admin.shared_setup(field_dialog_{{ id }});
  101.                     field_dialog_form_list_handle_action_{{ id }}();
  102.                     // open the dialog in modal mode
  103.                     field_dialog_{{ id }}.modal();
  104.                     Admin.setup_list_modal(field_dialog_{{ id }});
  105.                     loadNavPrometeo(field_dialog_content_{{ id }});
  106.                 }
  107.             });
  108.         };
  109.         // handle the add link
  110.         var field_dialog_form_add_{{ id }} = function(event) {
  111.             initialize_popup_{{ id }}();
  112.             event.preventDefault();
  113.             event.stopPropagation();
  114.             var a = jQuery(this);
  115.             field_dialog_content_{{ id }}.html('');
  116.             Admin.log('[{{ id }}|field_dialog_form_add] add link action');
  117.             // retrieve the form element from the related admin generator
  118.             jQuery.ajax({
  119.                 url: a.attr('href'),
  120.                 dataType: 'html',
  121.                 success: function(html) {
  122.                     Admin.log('[{{ id }}|field_dialog_form_add] ajax success', field_dialog_{{ id }});
  123.                     // populate the popup container
  124.                     field_dialog_content_{{ id }}.html(html);
  125.                     {% if associationadmin.label is not empty %}
  126.                     field_dialog_title_{{ id }}.html("{{ associationadmin.label|trans({}, associationadmin.translationdomain) }}");
  127.                     {% endif %}
  128.                     Admin.shared_setup(field_dialog_{{ id }});
  129.                     // capture the submit event to make an ajax call, ie : POST data to the
  130.                     // related create admin
  131.                     jQuery(document).on('click','#field_dialog_{{ id }} a', field_dialog_form_action_{{ id }});
  132.                     jQuery('form', field_dialog_{{ id }}).on('submit', field_dialog_form_action_{{ id }});
  133.                     // open the dialog in modal mode
  134.                     field_dialog_{{ id }}.modal();
  135.                     Admin.setup_list_modal(field_dialog_{{ id }});
  136.                 }
  137.             });
  138.         };
  139.         // handle the edit link
  140.         var field_dialog_form_edit_{{ id }} = function(event) {
  141.             initialize_popup_{{ id }}();
  142.             event.preventDefault();
  143.             event.stopPropagation();
  144.             var a = jQuery(this);
  145.             field_dialog_content_{{ id }}.html('');
  146.             Admin.log('[{{ id }}|field_dialog_form_edit] edit link action');
  147.             // retrieve the form element from the related admin generator
  148.             jQuery.ajax({
  149.                 url: a.attr('href'),
  150.                 dataType: 'html',
  151.                 success: function(html) {
  152.                     Admin.log('[{{ id }}|field_dialog_form_edit] ajax success', field_dialog_{{ id }});
  153.                     // populate the popup container
  154.                     field_dialog_content_{{ id }}.html(html);
  155.                     {% if associationadmin.label is not empty %}
  156.                     field_dialog_title_{{ id }}.html("{{ associationadmin.label|trans({}, associationadmin.translationdomain) }}");
  157.                     {% endif %}
  158.                     Admin.shared_setup(field_dialog_{{ id }});
  159.                     // capture the submit event to make an ajax call, ie : POST data to the
  160.                     // related create admin
  161.                     jQuery(document).on('click','#field_dialog_{{ id }} a', field_dialog_form_action_{{ id }});
  162.                     jQuery('form', field_dialog_{{ id }}).on('submit', field_dialog_form_action_{{ id }});
  163.                     // open the dialog in modal mode
  164.                     field_dialog_{{ id }}.modal();
  165.                     Admin.setup_list_modal(field_dialog_{{ id }});
  166.                 }
  167.             });
  168.         };
  169.         // handle the post data
  170.         var field_dialog_form_action_{{ id }} = function(event) {
  171.             var element = jQuery(this);
  172.             // return if the link is an anchor inside the same page
  173.             if (
  174.                 this.nodeName === 'A'
  175.                 && (
  176.                     element.attr('href').length === 0
  177.                     || element.attr('href')[0] === '#'
  178.                     || element.attr('href').substr(0, 11) === 'javascript:'
  179.                 )
  180.             ) {
  181.                 Admin.log('[{{ id }}|field_dialog_form_action] element is an anchor or a script, skipping action', this);
  182.                 return;
  183.             }
  184.             event.preventDefault();
  185.             event.stopPropagation();
  186.             Admin.log('[{{ id }}|field_dialog_form_action] action catch', this);
  187.             initialize_popup_{{ id }}();
  188.             if (this.nodeName == 'FORM') {
  189.                 var url  = element.attr('action');
  190.                 var type = element.attr('method');
  191.             } else if (this.nodeName == 'A') {
  192.                 var url  = element.attr('href');
  193.                 var type = 'GET';
  194.             } else {
  195.                 alert('unexpected element : @' + this.nodeName + '@');
  196.                 return;
  197.             }
  198.             if (element.hasClass('sonata-ba-action')) {
  199.                 Admin.log('[{{ id }}|field_dialog_form_action] reserved action stop catch all events');
  200.                 return;
  201.             }
  202.             var data = {
  203.                 _xml_http_request: true
  204.             }
  205.             var form = jQuery(this);
  206.             Admin.log('[{{ id }}|field_dialog_form_action] execute ajax call');
  207.             var oldErrorMessages = jQuery(field_dialog_content_{{ id }}).find('div.alert-danger');
  208.             // Remove old error messages.
  209.             if (oldErrorMessages.length > 0) {
  210.                 oldErrorMessages.remove();
  211.             }
  212.             $(this).find('.save-field-db').each(function (index, value) {
  213.                 if($(value).data("type") === "IMG")
  214.                 {
  215.                     $(value).data("value", $(value).find("+ a.view-imagen").attr("href"))
  216.                 }
  217.                 else {
  218.                     $(value).data("value", $(value).val());
  219.                 }
  220.                 reloadModelListType(value);
  221.             });
  222.             // the ajax post
  223.             jQuery(form).ajaxSubmit({
  224.                 url: url,
  225.                 type: type,
  226.                 headers: {
  227.                     Accept: 'application/json'
  228.                 },
  229.                 data: data,
  230.                 success: function(data) {
  231.                     Admin.log('[{{ id }}|field_dialog_form_action] ajax success');
  232.                     // if the crud action return ok, then the element has been added
  233.                     // so the widget container must be refresh with the last option available
  234.                     if (typeof data != 'string' && data.result == 'ok') {
  235.                         field_dialog_{{ id }}.modal('hide');
  236.                         {% if sonata_admin.edit == 'list' %}
  237.                         {#
  238.                         in this case we update the hidden input, and call the change event to
  239.                         retrieve the post information
  240.                         #}
  241.                         jQuery('#{{ id }}').val(data.objectId);
  242.                         jQuery('#{{ id }}').change();
  243.                         {% else %}
  244.                         // reload the form element
  245.                         jQuery('#field_widget_{{ id }}').closest('form').ajaxSubmit({
  246.                             url: '{{ path('sonata_admin_retrieve_form_element', {
  247.                                 '_sonata_admin': sonata_admin.admin.root.baseCodeRoute,
  248.                                 'elementId': id,
  249.                                 'subclass': sonata_admin.admin.hasActiveSubClass() ? sonata_admin.admin.getActiveSubclassCode() : null,
  250.                                 'objectId': sonata_admin.admin.root.id(sonata_admin.admin.root.subject),
  251.                                 'uniqid': sonata_admin.admin.root.uniqid,
  252.                             } + (
  253.                                 sonata_admin.admin.root.hasRequest()
  254.                                 ? sonata_admin.admin.root.request.attributes.get('_route_params', {})
  255.                                 : {}
  256.                             ) + app.request.query.all|default({})
  257.                             ) }}',
  258.                             data: {_xml_http_request: true },
  259.                             dataType: 'html',
  260.                             type: 'POST',
  261.                             success: function(html) {
  262.                                 jQuery('#field_container_{{ id }}').replaceWith(html);
  263.                                 var newElement = jQuery('#{{ id }} [value="' + data.objectId + '"]');
  264.                                 if (newElement.is("input")) {
  265.                                     newElement.attr('checked', 'checked');
  266.                                 } else {
  267.                                     newElement.attr('selected', 'selected');
  268.                                 }
  269.                                 jQuery('#field_container_{{ id }}').trigger('sonata-admin-append-form-element');
  270.                             }
  271.                         });
  272.                         {% endif %}
  273.                         return;
  274.                     }
  275.                     // otherwise, display form error
  276.                     field_dialog_content_{{ id }}.html(data);
  277.                     Admin.shared_setup(field_dialog_{{ id }});
  278.                     // reattach the event
  279.                     jQuery('form', field_dialog_{{ id }}).submit(field_dialog_form_action_{{ id }});
  280.                 },
  281.                 error: function(xhr) {
  282.                     var content = '';
  283.                     if ('application/json' === xhr.getResponseHeader('Content-Type')) {
  284.                         var jsonContent = JSON.parse(xhr.responseText);
  285.                         if (jsonContent.message) {
  286.                             content += '<div class="alert alert-danger alert-dismissable">'
  287.                                 + '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>'
  288.                                 + jsonContent.message
  289.                                 + '</div>';
  290.                         }
  291.                         if (jsonContent.errors) {
  292.                             for (error of jsonContent.errors) {
  293.                                 content += '<div class="alert alert-danger alert-dismissable">'
  294.                                     + '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>'
  295.                                     + error
  296.                                     + '</div>';
  297.                             }
  298.                         }
  299.                     } else {
  300.                         content += xhr.responseText;
  301.                     }
  302.                     // Display the error.
  303.                     field_dialog_content_{{ id }}.prepend(content);
  304.                     // Reset the submit buttons.
  305.                     $(form).find('button[type="submit"]').removeAttr('disabled');
  306.                 }
  307.             });
  308.             return false;
  309.         };
  310.         var field_dialog_{{ id }}         = false;
  311.         var field_dialog_content_{{ id }} = false;
  312.         var field_dialog_title_{{ id }}   = false;
  313.         function initialize_popup_{{ id }}() {
  314.             // initialize component
  315.             if (!field_dialog_{{ id }}) {
  316.                 field_dialog_{{ id }}         = jQuery("#field_dialog_{{ id }}");
  317.                 field_dialog_content_{{ id }} = jQuery(".modal-body", "#field_dialog_{{ id }}");
  318.                 field_dialog_title_{{ id }}   = jQuery(".modal-title", "#field_dialog_{{ id }}");
  319.                 // move the dialog as a child of the root element, nested form breaks html ...
  320.                 jQuery(document.body).append(field_dialog_{{ id }});
  321.                 Admin.log('[{{ id }}|field_dialog] move dialog container as a document child');
  322.             }
  323.         }
  324.         {#
  325.         This code is used to define the "add" popup
  326.         #}
  327.         // this function initializes the popup
  328.         // this can be only done this way as popup can be cascaded
  329.         function start_field_dialog_form_add_{{ id }}(link) {
  330.             // remove the html event
  331.             link.onclick = null;
  332.             initialize_popup_{{ id }}();
  333.             // add the jQuery event to the a element
  334.             jQuery(link)
  335.                 .click(field_dialog_form_add_{{ id }})
  336.                 .trigger('click')
  337.             ;
  338.             return false;
  339.         }
  340.         {#
  341.         This code is used to define the "edit" popup
  342.         #}
  343.         // this function initializes the popup
  344.         // this can only be done this way as popup can be cascaded
  345.         function start_field_dialog_form_edit_{{ id }}(link) {
  346.             // remove the html event
  347.             link.onclick = null;
  348.             initialize_popup_{{ id }}();
  349.             // add the jQuery event to the a element
  350.             jQuery(link)
  351.                 .click(field_dialog_form_edit_{{ id }})
  352.                 .trigger('click')
  353.             ;
  354.             return false;
  355.         }
  356.         if (field_dialog_{{ id }}) {
  357.             Admin.shared_setup(field_dialog_{{ id }});
  358.         }
  359.         {% if sonata_admin.edit == 'list' %}
  360.         {#
  361.         This code is used to defined the "list" popup
  362.         #}
  363.         // this function initializes the popup
  364.         // this can be only done this way as popup can be cascaded
  365.         function start_field_dialog_form_list_{{ id }}(link) {
  366.             link.onclick = null;
  367.             initialize_popup_{{ id }}();
  368.             // add the jQuery event to the a element
  369.             jQuery(link)
  370.                 .click(field_dialog_form_list_{{ id }})
  371.                 .trigger('click')
  372.             ;
  373.             return false;
  374.         }
  375.         function remove_selected_element_{{ id }}(link) {
  376.             link.onclick = null;
  377.             jQuery(link)
  378.                 .click(field_remove_element_{{ id }})
  379.                 .trigger('click')
  380.             ;
  381.             return false;
  382.         }
  383.         function field_remove_element_{{ id }}(event) {
  384.             event.preventDefault();
  385.             if (jQuery('#{{ id }} option').get(0)) {
  386.                 jQuery('#{{ id }}').attr('selectedIndex', '-1').children("option:selected").attr("selected", false);
  387.             }
  388.             jQuery('#{{ id }}').val('');
  389.             jQuery('#{{ id }}').trigger('change');
  390.             return false;
  391.         }
  392.         {#
  393.         attach onchange event on the input
  394.         #}
  395.         // update the label
  396.         jQuery('#{{ id }}').on('change', function(event) {
  397.             Admin.log('[{{ id }}|on:change] update the label');
  398.             var objectId = jQuery(this).val();
  399.             // Skip short object information call if object is missing.
  400.             if (undefined === objectId || null === objectId || '' === objectId) {
  401.                 jQuery('#field_widget_{{ id }}').html('{{ 'short_object_description_placeholder'|trans({}, 'SonataAdminBundle') }}');
  402.                 {% if btn_edit %}
  403.                 jQuery('#field_actions_{{ id }} a.btn-warning').addClass('hidden');
  404.                 {% endif %}
  405.                 return;
  406.             }
  407.             jQuery('#field_widget_{{ id }}').html("<span><img src=\"{{ asset('bundles/sonataadmin/images/ajax-loader.gif') }}\" style=\"vertical-align: middle; margin-right: 10px\"/>{{ 'loading_information'|trans([], 'SonataAdminBundle') }}</span>");
  408.             jQuery.ajax({
  409.                 type: 'GET',
  410.                 url: '{{ path('sonata_admin_short_object_information',{
  411.                     '_sonata_admin': associationadmin.baseCodeRoute,
  412.                     'objectId': 'OBJECT_ID',
  413.                     'uniqid': associationadmin.uniqid,
  414.                     'linkParameters': sonata_admin.field_description.option('link_parameters', {})
  415.                 } + (
  416.                     associationadmin.hasRequest()
  417.                     ? associationadmin.request.attributes.get('_route_params', {})
  418.                     : {}
  419.                 ) + app.request.query.all|default({})
  420.                 )}}'.replace('OBJECT_ID', objectId),
  421.                 dataType: 'html',
  422.                 success: function(html) {
  423.                     jQuery('#field_widget_{{ id }}').html(html);
  424.                     length = jQuery('#field_widget_{{ id }}').data("max_length")?jQuery('#field_widget_{{ id }}').data("max_length"):100;
  425.                     more = (length == 100 || length >= jQuery('#field_widget_{{ id }}').find(".inner-field-short-description > a").text().length) ? "" : "...";
  426.                     jQuery('#field_widget_{{ id }}').find(".inner-field-short-description > a").text((jQuery('#field_widget_{{ id }}').find(".inner-field-short-description > a").text().substr(0, length))+more);
  427.                 }
  428.             });
  429.             {% if btn_edit %}
  430.             var edit_button_url = '{{
  431.             associationadmin.generateUrl('edit', {(associationadmin.idParameter) : 'OBJECT_ID'})
  432.             }}'.replace('OBJECT_ID', objectId);
  433.             jQuery('#field_actions_{{ id }} a.btn-warning').removeClass('hidden').attr('href', edit_button_url);
  434.             {% endif %}
  435.         });
  436.         {% endif %}
  437.     </script>
  438.     <!-- / edit many association -->
  439. {% endautoescape %}