I'm still having question about the way of customizing the Portal for managing new types of Tickets.
What I want to do :
In my company, we need to manage different type of Tickets. So I created subclass A, B and C of Ticket's class.
Each Service / Sub Category of Service is linked to one of theses classes.
What I done :
1. I redefined the class ServiceSubcategory to modify the request_type field :
I redefined the method Ticket::CreateFromServiceSubcategory() in Ticket class to link the new request to the right class :
<classid="Ticket"_delta="merge"><methods><methodid="CreateFromServiceSubcategory"_delta="define"><comment>/**
*Instanciateanobjectoftherelevantclass,dependingontherequesttype
*@returnDBObject
*/
</comment><static>true</static><access>public</access><type>Factory</type><code><![CDATA[ static public function CreateFromServiceSubcategory($oServiceSubcategory) { $sType = $oServiceSubcategory->Get('request_type'); switch ($sType) { case 'A': $oRet = new A(); break; case 'B': $oRet = new B(); break; case 'C': $oRet = new C(); break; default: throw new Exception('Impossible de créer un ticket concernant le service '.$oServiceSubcategory->Get('friendlyname').' de type '.$sType.': Type inconnu'); } return $oRet; } ]]></code></method></methods></class>
When I try to create a new Ticket in Portal : I select a Service / Subcategory of Service (linked to A subclass of Ticket), I fill the form and I have the following error message :
Object not following integrity rules: issues = Unexpected value for attribute 'request_type': Value not allowed [informatique], class = UserRequest, id =
Where have I made a mistake?
Thanks for your help !
Regards,
Rafael.
Last edit: Rafael AINCIART 2018-12-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry, I complete my message. I also modified the scopes of Ticket :
<module_designs><module_designid="itop-portal"xsi:type="portal"_delta="merge"><classes><classid="Ticket"_delta="merge"><scopes><scopeid="all"_delta="redefine"><oql_view><![CDATA[SELECT Ticket AS T WHERE T.caller_id = :current_contact_id AND T.finalclass IN ('A', 'B', 'C')]]></oql_view><oql_edit><![CDATA[SELECT Ticket AS T]]></oql_edit></scope><scopeid="portal-power-user"_delta="redefine"><oql_view><![CDATA[SELECT Ticket AS T WHERE T.org_id = :current_contact->org_id AND T.finalclass IN ('A', 'B', 'C')]]></oql_view><oql_edit><![CDATA[SELECT Ticket AS T]]></oql_edit><allowed_profiles><allowed_profileid="Portal power user"/></allowed_profiles></scope></scopes></class></classes></module_design></module_designs>
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Any idea about my issue ?
- I created new classes as childs of Ticket class
- I redefined the class ServiceSubcategory to modify the request_type field
- I overload the method Ticket::CreateFromServiceSubcategory() in Ticket class to link the new request to the right class
- I modify the scopes in Portal to allow the new class instead of UserRequest and Incident
But a new request still point to UserRequest type...
Something must be missing.
Rafael.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mind the backslash before the class and the omission of parenthesis at the end
You can find an example of this in the datamodels/2.x/itop-full-itil/datamodel.itop-full-itil.xml file. FYI, if you had choosen the ITIL Request management and ITIL Change management options during the setup, this would already be done.
Hope it helps!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is several weeks now since I try to customize itop Portal to manage new types of Tickets but I don't understand why it's not working...
1. I created new classes as childs of Ticket class
2. I redefined the class ServiceSubcategory to modify the request_type field
3. I overload the method Ticket::CreateFromServiceSubcategory() in Ticket class to link the new request to the right class
4. I modify the scopes in Portal to allow the new class instead of UserRequest and Incident
5. I give the appropriates rights on the new classes for the Portal users
When I execute the Portal and try to create a new Ticket (with one of the new type), the form appears but it's impossible to submit it. No error message, nothing happend. It is as if the javacript code to execute the ajax request is missing.
I have installed a new instance of itop with the full itil management (but without change management) but the result is still the same.
In debug mode (netbeans-xdebug), I have no error : the CreateFromServiceSubcategory($oServiceSubcategory) function is called and a new class is created. But impossible to save the form.
In CreateFromServiceSubcategory(), I have set the request_type property to the correct value :
Hello,
What do you mean by '"the form appears but it's impossible to submit it" ?
Are the buttons present at the end of the form dialog ?
If yes, do you see any JS error in your browser console ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The modal window of the form is normally loaded and, in the code, the corresponding object is created.
I can see the buttons to save the new Ticket in the bottom of the form.
The only problem is that I can't save the form : there is no result when I click on the "Apply" button (but it works on the "Cancel" one).
I have no error message (even if I add the debug=true in the url).
I use the chrome console to inspect the client side code but I don't see what can be wrong...
The error messages I can see :
* GET http://prh2.localhost/env-production/fonts/glyphicons-halflings-regular.woff2 net::ERR_ABORTED 404 (Not Found)
* GET http://prh2.localhost/env-production/fonts/glyphicons-halflings-regular.woff net::ERR_ABORTED 404 (Not Found)
The script executed by the button :
$(document).ready(function(){//FormfieldsetdeclarationvaroFieldSet_objectformticketcreate5c48332d11a57=$('#objectform-ticket-create-5c48332d11a57 > .form_fields').field_set({"fields_impacts":{"org_id":["service_id"],"service_id":["servicesubcategory_id"],"request_type":["servicesubcategory_id"]},"form_path":"objectform-ticket-create-5c48332d11a57","fields_list":{"service_id":{"id":"service_id","html":"<div class=\"form-group form_group_small \"><div class=\"form_field_label\"><label for=\"field_service_id_5c48332d2d9cb\" class=\"control-label\">service id<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><div class=\"row\"><div class=\"col-xs-12 col-sm-12 col-md-12\"><select id=\"field_service_id_5c48332d2d9cb\" name=\"service_id\" class=\"form-control\"><option value=\"\">-- choisir une valeur --<\/option><option value=\"1\" >Analytique<\/option><option value=\"2\" >Appli Web<\/option><option value=\"3\" >Conseil légal<\/option><option value=\"4\" >Droits utilisateurs<\/option><option value=\"5\" >Fichier de contrôle<\/option><option value=\"6\" >Installations<\/option><option value=\"7\" selected >Utilisateurs<\/option><\/select><\/div><div class=\"col-xs-0 col-sm-0 col-md-0 text-right\"><\/div><\/div><\/div><\/div>","js_inline":" \t\t\t\t\t\t$(\"#field_service_id_5c48332d2d9cb\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\t$(\"[data-field-id='service_id'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\n\t\t\t\t\t\t\t'validators': []\n\t\t\t\t\t\t});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"servicesubcategory_id":{"id":"servicesubcategory_id","html":"<div class=\"form-group form_group_small \"><div class=\"form_field_label\"><label for=\"field_servicesubcategory_id_5c48332d3d6cc\" class=\"control-label\">servicesubcategory id<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><div class=\"row\"><div class=\"col-xs-12 col-sm-12 col-md-12\"><select id=\"field_servicesubcategory_id_5c48332d3d6cc\" name=\"servicesubcategory_id\" class=\"form-control\"><option value=\"\">-- choisir une valeur --<\/option><option value=\"5\" selected >Création<\/option><option value=\"11\" >Modification<\/option><option value=\"15\" >Suppression<\/option><\/select><\/div><div class=\"col-xs-0 col-sm-0 col-md-0 text-right\"><\/div><\/div><\/div><\/div>","js_inline":" \t\t\t\t\t\t$(\"#field_servicesubcategory_id_5c48332d3d6cc\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\t$(\"[data-field-id='servicesubcategory_id'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\n\t\t\t\t\t\t\t'validators': []\n\t\t\t\t\t\t});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"impact":{"id":"impact","html":"<div class=\"form-group form_group_small form_mandatory\"><div class=\"form_field_label\"><label for=\"field_impact_5c48332d46eb4\" class=\"control-label\">impact<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><select id=\"field_impact_5c48332d46eb4\" name=\"impact\" class=\"form-control\"><option value=\"\" >-- choisir une valeur --<\/option><option value=\"1\" selected >1<\/option><option value=\"2\" >2<\/option><option value=\"3\" >3<\/option><\/select><\/div><\/div>","js_inline":" \t\t\t\t\t$(\"#field_impact_5c48332d46eb4\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t$(\"[data-field-id='impact'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\"validators\":{\"mandatory\":{\"reg_exp\":\".*\\\\S.*\",\"message\":\"Veuillez remplir ce champ\"}}});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"urgency":{"id":"urgency","html":"<div class=\"form-group form_group_small form_mandatory\"><div class=\"form_field_label\"><label for=\"field_urgency_5c48332d49117\" class=\"control-label\">urgency<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><select id=\"field_urgency_5c48332d49117\" name=\"urgency\" class=\"form-control\"><option value=\"\" >-- choisir une valeur --<\/option><option value=\"1\" >1<\/option><option value=\"2\" >2<\/option><option value=\"3\" >3<\/option><option value=\"4\" selected >4<\/option><\/select><\/div><\/div>","js_inline":" \t\t\t\t\t$(\"#field_urgency_5c48332d49117\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t$(\"[data-field-id='urgency'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\"validators\":{\"mandatory\":{\"reg_exp\":\".*\\\\S.*\",\"message\":\"Veuillez remplir ce champ\"}}});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"title":{"id":"title","html":"<div class=\"form-group form_group_small form_mandatory\"><div class=\"form_field_label\"><label for=\"field_title_5c48332d4ba4d\" class=\"control-label\">Titre<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><input type=\"text\" id=\"field_title_5c48332d4ba4d\" name=\"title\" value=\"\" class=\"form-control\" maxlength=\"255\" \/><\/div><\/div>","js_inline":" \t\t\t\t\t$(\"#field_title_5c48332d4ba4d\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t$(\"[data-field-id='title'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\"validators\":{\"mandatory\":{\"reg_exp\":\".*\\\\S.*\",\"message\":\"Veuillez remplir ce champ\"}}});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"description":{"id":"description","html":"<div class=\"form-group form_mandatory\"><div class=\"form_field_label\"><label for=\"field_description_5c48332d4cbd0\" class=\"control-label\">Description<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><div><textarea id=\"field_description_5c48332d4cbd0\" name=\"description\" class=\"form-control\" rows=\"8\"><\/textarea><\/div><\/div><\/div>","js_inline":" \t\t\t\t\t\t\t$('#field_description_5c48332d4cbd0').addClass('htmlEditor');\n\t\t\t\t\t\t\t$('#field_description_5c48332d4cbd0').ckeditor(function(){}, {language: 'fr fr', contentsLanguage: 'fr fr'});\n\t\t\/\/ Hook the file upload of all CKEditor instances\n\t\t$('.htmlEditor').each(function() {\n\t\t\tvar oEditor = $(this).ckeditorGet();\n\t\t\toEditor.config.extraPlugins = 'font,uploadimage';\n\t\t\toEditor.config.uploadUrl = 'http:\/\/prh2.localhost\/'+'pages\/ajax.render.php';\n\t\t\toEditor.config.filebrowserBrowseUrl = 'http:\/\/prh2.localhost\/'+'pages\/ajax.render.php?operation=cke_browse&temp_id=1sgctap661qgcflo8hgta6v0av_0072506001548235565&obj_class=Informatique&obj_key=-2';\n\t\t\toEditor.on( 'fileUploadResponse', function( evt ) {\n\t\t\t\tvar fileLoader = evt.data.fileLoader;\n\t\t\t\tvar xhr = fileLoader.xhr;\n\t\t\t\tvar data = evt.data;\n\t\t\t\ttry {\n\t\t\t var response = JSON.parse( xhr.responseText );\n\t\t\n\t\t\t \/\/ Error message does not need to mean that upload finished unsuccessfully.\n\t\t\t \/\/ It could mean that ex. file name was changes during upload due to naming collision.\n\t\t\t if ( response.error && response.error.message ) {\n\t\t\t data.message = response.error.message;\n\t\t\t }\n\t\t\n\t\t\t \/\/ But !uploaded means error.\n\t\t\t if ( !response.uploaded ) {\n\t\t\t evt.cancel();\n\t\t\t } else {\n\t\t\t data.fileName = response.fileName;\n\t\t\t\tdata.url = response.url;\n\t\t\t\t\t\t\n\t\t\t \/\/ Do not call the default listener.\n\t\t\t evt.stop();\n\t\t\t }\n\t\t\t } catch ( err ) {\n\t\t\t \/\/ Response parsing error.\n\t\t\t data.message = fileLoader.lang.filetools.responseError;\n\t\t\t window.console && window.console.log( xhr.responseText );\n\t\t\n\t\t\t evt.cancel();\n\t\t\t }\n\t\t\t} );\n\t\n\t\t\toEditor.on( 'fileUploadRequest', function( evt ) {\n\t\t\t\tevt.data.fileLoader.uploadUrl += '?operation=cke_img_upload&temp_id=1sgctap661qgcflo8hgta6v0av_0072506001548235565&obj_class=Informatique';\n\t\t\t}, null, null, 4 ); \/\/ Listener with priority 4 will be executed before priority 5.\n\t\t\n\t\t\toEditor.on( 'instanceReady', function() {\n\t\t\t\tif(!CKEDITOR.env.iOS && $('#'+oEditor.id+'_toolbox .editor_magnifier').length == 0)\n\t\t\t\t{\n\t\t\t\t\t$('#'+oEditor.id+'_toolbox').append('<span class=\"editor_magnifier\" title=\"Agrandir \/ Minimiser\" style=\"display:block;width:12px;height:11px;border:1px #A6A6A6 solid;cursor:pointer; background-image:url(\\'http:\/\/prh2.localhost\/\/images\/full-screen.png\\')\"> <\/span>');\n\t\t\t\t\t$('#'+oEditor.id+'_toolbox .editor_magnifier').on('click', function() {\n\t\t\t\t\t\t\toEditor.execCommand('maximize');\n\t\t\t\t\t\t\tif ($(this).closest('.cke_maximized').length != 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$('#'+oEditor.id+'_toolbar_collapser').trigger('click');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (oEditor.widgets.registered.uploadimage)\n\t\t\t\t{\n\t\t\t\t\toEditor.widgets.registered.uploadimage.onUploaded = function( upload ) {\n\t\t\t\t\tvar oData = JSON.parse(upload.xhr.responseText);\n\t\t\t\t\tthis.replaceWith( '<img src=\"' + upload.url + '\" ' +\n\t\t\t\t\t\t'width=\"' + oData.width + '\" ' +\n\t\t\t\t\t\t\t'height=\"' + oData.height + '\">' );\n\t\t\t\t }\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\t\t\t\t$(\"#field_description_5c48332d4cbd0\").off(\"change keyup\").on(\"change keyup\", function(){\n\t\t\t\t\t\tvar me = this;\n\n\t\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\t\tid: $(me).attr(\"id\"),\n\t\t\t\t\t\t\tname: $(me).closest(\".form_field\").attr(\"data-field-id\"),\n\t\t\t\t\t\t\tvalue: $(me).val()\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n $(\"[data-field-id='description'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field_html({\n validators: {\"mandatory\":{\"reg_exp\":\".*\\\\S.*\",\"message\":\"Veuillez remplir ce champ\"}},\n set_current_value_callback: function(me, oEvent, oData){ $(me.element).find('textarea').val(oData); }\n });\n$('img[data-img-id]').each(function() {\n\tif ($(this).width() > 250)\n\t{\n\t\t$(this).css({'max-width': '250px', width: '', height: '', 'max-height': ''});\n\t}\n\t$(this).addClass('inline-image').attr('href', $(this).attr('src'));\n}).magnificPopup({type: 'image', closeOnContentClick: true });\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"contacts_list":{"id":"contacts_list","html":"<div class=\"form-group \"><label for=\"field_contacts_list_5c48332d4e09b\" class=\"control-label\"><a id=\"form_linkedset_toggler_field_contacts_list_5c48332d4e09b\" class=\"form_linkedset_toggler collapsed\" data-toggle=\"collapse\" href=\"#form_linkedset_wrapper_field_contacts_list_5c48332d4e09b\" aria-expanded=\"false\" aria-controls=\"form_linkedset_wrapper_field_contacts_list_5c48332d4e09b\">Contacts<span class=\"text\">0<\/span><span class=\"glyphicon glyphicon-menu-down collapsed\"><\/><\/a><\/label><div class=\"help-block\"><\/div>\t\t\t\t<div class=\"form_linkedset_wrapper collapse\" id=\"form_linkedset_wrapper_field_contacts_list_5c48332d4e09b\">\n\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t<input type=\"hidden\" id=\"field_contacts_list_5c48332d4e09b\" name=\"contacts_list\" value=\"{"current":[]}\" \/>\n\t\t\t\t\t\t\t<table id=\"table_field_contacts_list_5c48332d4e09b\" data-field-id=\"contacts_list\" class=\"table table-striped table-bordered responsive\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t\t\t<\/table>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t\t<div class=\"btn-group\" role=\"group\">\n\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-danger\" id=\"btn_remove_field_contacts_list_5c48332d4e09b\" title=\"Enlever\" disabled><span class=\"glyphicon glyphicon-minus\"><\/span><\/button>\n\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-default\" id=\"btn_add_field_contacts_list_5c48332d4e09b\" title=\" Ajouter... \"><span class=\"glyphicon glyphicon-plus\"><\/span><\/button>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div><\/div><\/div>","js_inline":" \t\t\t\t\/\/ Collapse handlers\n\t\t\t\t\/\/ - Collapsing by default to optimize form space\n\t\t\t\t\/\/ It would be better to be able to construct the widget as collapsed, but in this case, datatables thinks the container is very small and therefore renders the table as if it was in microbox.\n\t\t\t\t$('#form_linkedset_wrapper_field_contacts_list_5c48332d4e09b').collapse({toggle: false});\n\t\t\t\t\/\/ - Change toggle icon class\n\t\t\t\t$('#form_linkedset_wrapper_field_contacts_list_5c48332d4e09b').on('shown.bs.collapse', function(){\n\t\t\t\t\t\/\/ Creating the table if null (first expand). If we create it on start, it will be displayed as if it was in a micro screen due to the div being \"display: none;\"\n\t\t\t\t\tif(oTable_field_contacts_list_5c48332d4e09b === undefined)\n\t\t\t\t\t{\n\t\t\t\t\t\tbuildTable_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.on('show.bs.collapse', function(){\n\t\t\t\t\t$('#form_linkedset_toggler_field_contacts_list_5c48332d4e09b > span.glyphicon').removeClass('glyphicon-menu-down collapsed').addClass('glyphicon-menu-down');\n\t\t\t\t})\n\t\t\t\t.on('hide.bs.collapse', function(){\n\t\t\t\t\t$('#form_linkedset_toggler_field_contacts_list_5c48332d4e09b > span.glyphicon').removeClass('glyphicon-menu-down').addClass('glyphicon-menu-down collapsed');\n\t\t\t\t});\n\n\t\t\t\t\/\/ Places a loader in the empty datatables\n\t\t\t\t$('#table_field_contacts_list_5c48332d4e09b > tbody').html('<tr><td class=\"datatables_overlay\" colspan=\"100\">' + $('#page_overlay').html() + '<\/td><\/tr>');\n\n\t\t\t\t\/\/ Prepares data for datatables\n\t\t\t\tvar oColumnProperties_field_contacts_list_5c48332d4e09b = {\"friendlyname\":\"Nom complet\",\"status\":\"Statut\",\"org_id\":\"Organisation\",\"function\":\"Fonction\"};\n\t\t\t\tvar oRawDatas_field_contacts_list_5c48332d4e09b = [];\n\t\t\t\tvar oTable_field_contacts_list_5c48332d4e09b;\n\t\t\t\tvar oSelectedItems_field_contacts_list_5c48332d4e09b = {};\n\n\t\t\t\tvar getColumnsDefinition_field_contacts_list_5c48332d4e09b = function()\n\t\t\t\t{\n\t\t\t\t\tvar aColumnsDefinition = [];\n\n\t\t\t\t\tif(true)\n\t\t\t\t\t{\n\t\t\t\t\t\taColumnsDefinition.push({\n\t\t\t\t\t\t\t\t\"width\": \"auto\",\n\t\t\t\t\t\t\t\t\"searchable\": false,\n\t\t\t\t\t\t\t\t\"sortable\": false,\n\t\t\t\t\t\t\t\t\"title\": '<span class=\"row_input\"><input type=\"checkbox\" id=\"field_contacts_list_5c48332d4e09b_check_all\" name=\"field_contacts_list_5c48332d4e09b_check_all\" title=\"Tout cocher \/ Tout décocher\" \/><\/span>',\n\t\t\t\t\t\t\t\t\"type\": \"html\",\n\t\t\t\t\t\t\t\t\"data\": \"\",\n\t\t\t\t\t\t\t\t\"render\": function(data, type, row)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar oCheckboxElem = $('<span class=\"row_input\"><input type=\"checkbox\" name=\"field_contacts_list_5c48332d4e09b\" \/><\/span>');\n\t\t\t\t\t\t\t\t\toCheckboxElem.find(':input').attr('data-object-id', row.id).attr('data-target-object-id', row.target_id);\n\t\t\t\t\t\t\t\t\treturn oCheckboxElem.prop('outerHTML');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tfor(sKey in oColumnProperties_field_contacts_list_5c48332d4e09b)\n\t\t\t\t\t{\n\t\t\t\t\t\t\/\/ Level main column\n\t\t\t\t\t\taColumnsDefinition.push({\n\t\t\t\t\t\t\t\"width\": \"auto\",\n\t\t\t\t\t\t\t\"searchable\": true,\n\t\t\t\t\t\t\t\"sortable\": true,\n\t\t\t\t\t\t\t\"title\": oColumnProperties_field_contacts_list_5c48332d4e09b[sKey],\n\t\t\t\t\t\t\t\"defaultContent\": \"\",\n\t\t\t\t\t\t\t\"type\": \"html\",\n\t\t\t\t\t\t\t\"data\": \"attributes.\"+sKey+\".att_code\",\n\t\t\t\t\t\t\t\"render\": function(data, type, row){\n\t\t\t\t\t\t\t\tvar cellElem;\n\n\t\t\t\t\t\t\t\t\/\/ Preparing the cell data\n\t\t\t\t\t\t\t\tif(row.attributes[data].url !== undefined)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcellElem = $('<a><\/a>');\n\t\t\t\t\t\t\t\t\tcellElem.attr('href', row.attributes[data].url);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcellElem = $('<span><\/span>');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcellElem.html('<span>' + row.attributes[data].value + '<\/span>');\n\n\t\t\t\t\t\t\t\treturn cellElem.prop('outerHTML');\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn aColumnsDefinition;\n\t\t\t\t};\n\n\t\t\t\t\/\/ Helper to build the datatable\n\t\t\t\t\/\/ Note : Those options should be externalized in an library so we can use them on any DataTables for the portal.\n\t\t\t\t\/\/ We would just have to override \/ complete the necessary elements\n\t\t\t\tvar buildTable_field_contacts_list_5c48332d4e09b = function()\n\t\t\t\t{\n\t\t\t\t\tvar iDefaultOrderColumnIndex = (true) ? 1 : 0;\n\n\t\t\t\t\t\/\/ Instanciates datatables\n\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b = $('#table_field_contacts_list_5c48332d4e09b').DataTable({\n\t\t\t\t\t\t\"language\": {\n\t\t\t\t\t\t\t\"emptyTable\":\t\"La liste est vide, utilisez le bouton "Ajouter..." pour ajouter des objets.\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"displayLength\": -1,\n\t\t\t\t\t\t\"scrollY\": \"300px\",\n\t\t\t\t\t\t\"scrollCollapse\": true,\n\t\t\t\t\t\t\"retrieve\": true,\n\t\t\t\t\t\t\"order\": [[iDefaultOrderColumnIndex, \"asc\"]],\n\t\t\t\t\t\t\"dom\": 't',\n\t\t\t\t\t\t\"columns\": getColumnsDefinition_field_contacts_list_5c48332d4e09b(),\n\t\t\t\t\t\t\"select\": {\"style\": \"multi\"},\n\t\t\t\t\t\t\"rowId\": \"id\",\n\t\t\t\t\t\t\"data\": oRawDatas_field_contacts_list_5c48332d4e09b,\n\t\t\t\t\t\t\"rowCallback\": function(oRow, oData){\n\t\t\t\t\t\t\t\/\/ Opening in a new modal on click\n\t\t\t\t\t\t\t$(oRow).find('a').off('click').on('click', function(oEvent){\n\t\t\t\t\t\t\t\t\/\/ Prevents link opening.\n\t\t\t\t\t\t\t\toEvent.preventDefault();\n\t\t\t\t\t\t\t\t\/\/ Prevents row selection\n\t\t\t\t\t\t\t\toEvent.stopPropagation();\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\/\/ Note : This could be better if we check for an existing modal first instead of always creating a new one\n\t\t\t\t\t\t\t\tvar oModalElem = $('#modal-for-all').clone();\n\t\t\t\t\t\t\t\toModalElem.attr('id', '').appendTo('body');\n\t\t\t\t\t\t\t\t\/\/ Loading content\n\t\t\t\t\t\t\t\toModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html());\n\t\t\t\t\t\t\t\toModalElem.find('.modal-content').load(\n\t\t\t\t\t\t\t\t\t$(this).attr('href'),\n\t\t\t\t\t\t\t\t\t{},\n\t\t\t function(sResponseText, sStatus, oXHR){\n\t\t\t \/\/ Hiding modal in case of error as the general AJAX error handler will display a message\n\t\t\t if(sStatus === 'error')\n\t\t\t {\n\t\t\t oModalElem.modal('hide');\n\t\t\t }\n\t\t\t }\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\toModalElem.modal('show');\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\t\t\n\t\t\t\t\t\/\/ Handles items selection\/deselection\n\t\t\t\t\t\/\/ - Directly on the table\n\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.off('select').on('select', function(oEvent, dt, type, indexes){\n\t\t\t\t\t\tvar aData = oTable_field_contacts_list_5c48332d4e09b.rows(indexes).data().toArray();\n\n\t\t\t\t\t\t\/\/ Checking input\n\t\t\t\t\t\t$('#table_field_contacts_list_5c48332d4e09b tbody tr[role=\"row\"].selected td:first-child input').prop('checked', true);\n\t\t\t\t\t\t\/\/ Saving values in temp array\n\t\t\t\t\t\tfor(var i in aData)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar iItemId = aData[i].id;\n\t\t\t\t\t\t\tif(!(iItemId in oSelectedItems_field_contacts_list_5c48332d4e09b))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toSelectedItems_field_contacts_list_5c48332d4e09b[iItemId] = aData[i].name;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\/\/ Updating remove button\n\t\t\t\t\t\tupdateRemoveButtonState_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t});\n\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.off('deselect').on('deselect', function(oEvent, dt, type, indexes){\n\t\t\t\t\t\tvar aData = oTable_field_contacts_list_5c48332d4e09b.rows(indexes).data().toArray();\n\n\t\t\t\t\t\t\/\/ Checking input\n\t\t\t\t\t\t$('#table_field_contacts_list_5c48332d4e09b tbody tr[role=\"row\"]:not(.selected) td:first-child input').prop('checked', false);\n\t\t\t\t\t\t\/\/ Saving values in temp array\n\t\t\t\t\t\tfor(var i in aData)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar iItemId = aData[i].id;\n\t\t\t\t\t\t\tif(iItemId in oSelectedItems_field_contacts_list_5c48332d4e09b)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdelete oSelectedItems_field_contacts_list_5c48332d4e09b[iItemId];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\/\/ Unchecking global checkbox\n\t\t\t\t\t\t$('#field_contacts_list_5c48332d4e09b_check_all').prop('checked', false);\n\t\t\t\t\t\t\/\/ Updating remove button\n\t\t\t\t\t\tupdateRemoveButtonState_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t});\n\t\t\t\t\t\/\/ - From the global button\n\t\t\t\t\t$('#field_contacts_list_5c48332d4e09b_check_all').off('click').on('click', function(oEvent){\n\t\t\t\t\t\tif($(this).prop('checked'))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.rows().select();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.rows().deselect();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdateRemoveButtonState_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t});\n\t\t\t\t};\n $(\"[data-field-id='contacts_list'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\n\t\t\t\t\t'validators': [],\n\t\t\t\t\t'get_current_value_callback': function(me, oEvent, oData){\n\t\t\t\t\t\tvar value = null;\n\n\t\t\t\t\t\t\/\/ Retrieving JSON value as a string and not an object\n\t\t\t\t\t\t\/\/\n\t\t\t\t\t\t\/\/ Note : The value is passed as a string instead of an array because the attribute would not be included in the posted data when empty.\n\t\t\t\t\t\t\/\/ Which was an issue when deleting all objects from linkedset\n\t\t\t\t\t\t\/\/\n\t\t\t\t\t\t\/\/ Old code : value = JSON.parse(me.element.find('#field_contacts_list_5c48332d4e09b').val());\n\t\t\t\t\t\tvalue = me.element.find('#field_contacts_list_5c48332d4e09b').val();\n\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t},\n\t\t\t\t\t'set_current_value_callback': function(me, oEvent, oData){\n\t\t\t\t\t\t\/\/ When we have data (meaning that we picked objects from search)\n\t\t\t\t\t\tif(oData !== undefined && Object.keys(oData.values).length > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\/\/ Showing loader while retrieving informations\n\t\t\t\t\t\t\t$('#page_overlay').fadeIn(200);\n\n\t\t\t\t\t\t\t\/\/ Retrieving new rows ids\n\t\t\t\t\t\t\tvar aObjectIds = Object.keys(oData.values);\n\n\t\t\t\t\t\t\t\/\/ Retrieving rows informations so we can add them\n\t\t\t\t\t\t\t$.post(\n\t\t\t\t\t\t\t\t'\/pages\/exec.php\/object\/get-informations\/json?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal',\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tsObjectClass: 'Contact',\n\t\t\t\t\t\t\t\t\taObjectIds: aObjectIds,\n\t\t\t\t\t\t\t\t\taObjectAttCodes: [\"friendlyname\",\"status\",\"org_id\",\"function\"]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tfunction(oData){\n\t\t\t\t\t\t\t\t\t\/\/ Updating datatables\n\t\t\t\t\t\t\t\t\tif(oData.items !== undefined)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t for(var i in oData.items)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\/\/ Adding target item id information\n\t\t\t\t\t\t\t\t\t\t\toData.items[i].target_id = oData.items[i].id;\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\/\/ Adding item to table only if it's not already there\n\t\t\t\t\t\t\t\t\t\t\tif($('#table_field_contacts_list_5c48332d4e09b tr[role=\"row\"] > td input[data-target-object-id=\"' + oData.items[i].target_id + '\"], #table_field_contacts_list_5c48332d4e09b tr[role=\"row\"] > td input[data-target-object-id=\"' + (oData.items[i].target_id*-1) + '\"]').length === 0)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\/\/ Making id negative in order to recognize it when persisting\n\t\t\t\t\t\t\t\t\t\t\t\toData.items[i].id = -1 * parseInt(oData.items[i].id);\n\t\t\t\t\t\t\t\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.row.add(oData.items[i]);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.draw();\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\/\/ Updating input\n\t\t\t\t\t\t updateInputValue_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.done(function(oData){\n\t\t\t\t\t\t\t\t\/\/ Updating items count\n\t\t\t\t\t\t\t\tupdateItemCount_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t\t\t\t\/\/ Updating global checkbox\n\t\t\t\t\t\t\t\t$('#field_contacts_list_5c48332d4e09b_check_all').prop('checked', false);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.always(function(oData){\n\t\t\t\t\t\t\t\t\/\/ Hiding loader\n\t\t\t\t\t\t\t\t$('#page_overlay').fadeOut(200);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\/\/ We come from a button\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t \/\/ Updating input\n\t\t\t\t\t\t updateInputValue_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t\t\t\/\/ Updating items count\n\t\t\t\t\t\t\tupdateItemCount_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t\t\t\/\/ Updating global checkbox\n\t\t\t\t\t\t\t$('#field_contacts_list_5c48332d4e09b_check_all').prop('checked', false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t\t\/\/ Handles items selection\/deselection\n\t\t\t\t\t\/\/ - Remove button state handler\n\t\t\t\t\tvar updateRemoveButtonState_field_contacts_list_5c48332d4e09b = function()\n\t\t\t\t\t{\n\t\t\t\t\t\tvar bIsDisabled = (Object.keys(oSelectedItems_field_contacts_list_5c48332d4e09b).length == 0);\n\t\t\t\t\t\t$('#btn_remove_field_contacts_list_5c48332d4e09b').prop('disabled', bIsDisabled);\n\t\t\t\t\t};\n\t\t\t\t\t\/\/ - Item count state handler\n\t\t\t\t\tvar updateItemCount_field_contacts_list_5c48332d4e09b = function()\n\t\t\t\t\t{\n\t\t\t\t\t\t$('#form_linkedset_toggler_field_contacts_list_5c48332d4e09b > .text').text( oTable_field_contacts_list_5c48332d4e09b.rows().count() );\n\t\t\t\t\t};\n\t\t\t\t\t\/\/ - Field input handler\n\t\t\t\t\tvar updateInputValue_field_contacts_list_5c48332d4e09b = function()\n\t\t\t\t\t{\n\t\t\t\t\t \/\/ Retrieving table rows\n\t\t\t\t\t var aData = oTable_field_contacts_list_5c48332d4e09b.rows().data().toArray();\n\t\t\t\t\t\n\t\t\t\t\t \/\/ Retrieving input values\n var oValues = JSON.parse($('#field_contacts_list_5c48332d4e09b').val());\n oValues.add = {};\n oValues.remove = {};\n\n\t\t\t\t\t \/\/ Checking removed objects\n\t\t\t\t\t for(var i in oValues.current)\n\t\t\t\t\t {\n\t\t\t\t\t if($('#table_field_contacts_list_5c48332d4e09b tr[role=\"row\"] input[data-object-id=\"'+i+'\"]').length === 0)\n {\n oValues.remove[i] = {};\n }\n\t\t\t\t\t }\n\t\t\t\t\t\n\t\t\t\t\t \/\/ Checking added objects\n\t\t\t\t\t for(var i in aData)\n\t\t\t\t\t {\n\t\t\t\t\t if(oValues.current[aData[i].id] === undefined)\n\t\t\t\t\t {\n\t\t\t\t\t oValues.add[aData[i].target_id] = {};\n }\n\t\t\t\t\t }\n\t\t\t\t\t\n \/\/ Setting input values\n $('#field_contacts_list_5c48332d4e09b').val(JSON.stringify(oValues));\n\t\t\t\t\t};\n\n\t\t\t\t\t\/\/ Handles items remove\/add\n\t\t\t\t\t$('#btn_remove_field_contacts_list_5c48332d4e09b').off('click').on('click', function(){\n\t\t\t\t\t\t\/\/ Removing items from table\n\t\t\t\t\t\toTable_field_contacts_list_5c48332d4e09b.rows({selected: true}).remove().draw();\n\t\t\t\t\t\t\/\/ Resetting selected items\n\t\t\t\t\t\toSelectedItems_field_contacts_list_5c48332d4e09b = {};\n\t\t\t\t\t\t\/\/ Updating form value\n\t\t\t\t\t\t$(\"[data-field-id='contacts_list'][data-form-path='objectform-ticket-create-5c48332d11a57']\").triggerHandler('set_current_value');\n\t\t\t\t\t\t\/\/ Updating global checkbox state\n\t\t\t\t\t\t$('#field_contacts_list_5c48332d4e09b_check_all').prop('checked', false);\n\t\t\t\t\t\t\/\/ Updating remove button\n\t\t\t\t\t\tupdateRemoveButtonState_field_contacts_list_5c48332d4e09b();\n\t\t\t\t\t});\n\t\t\t\t\t$('#btn_add_field_contacts_list_5c48332d4e09b').off('click').on('click', function(){\n\t\t\t\t\t\t\/\/ Preparing current values\n\t\t\t\t\t\tvar aObjectIdsToIgnore = [];\n\t\t\t\t\t\t$('#table_field_contacts_list_5c48332d4e09b tr[role=\"row\"] > td input[data-target-object-id]').each(function(iIndex, oElem){\n\t\t\t\t\t\t\taObjectIdsToIgnore.push( $(oElem).attr('data-target-object-id') );\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\/\/ Creating a new modal\n\t\t\t\t\t\tvar oModalElem;\n\t\t\t\t\t\tif($('.modal[data-source-element=\"btn_add_field_contacts_list_5c48332d4e09b\"]').length === 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toModalElem = $('#modal-for-all').clone();\n\t\t\t\t\t\t\toModalElem.attr('id', '').attr('data-source-element', 'btn_add_field_contacts_list_5c48332d4e09b').appendTo('body');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toModalElem = $('.modal[data-source-element=\"btn_add_field_contacts_list_5c48332d4e09b\"]').first();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\/\/ Resizing to small modal\n\t\t\t\t\t\toModalElem.find('.modal-dialog').removeClass('modal-sm').addClass('modal-lg');\n\t\t\t\t\t\t\/\/ Loading content\n\t\t\t\t\t\toModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html());\n\t\t\t\t\t\toModalElem.find('.modal-content').load(\n\t\t\t\t\t\t\t'\/pages\/exec.php\/object\/search\/from-attribute\/contacts_list\/Informatique?ar_token=eyJydWxlcyI6WyJjb250YWN0LXRvLXVzZXJyZXF1ZXN0Iiwic2VydmljZXN1YmNhdGVnb3J5LXRvLXVzZXJyZXF1ZXN0IiwiZ28tdG8tb3Blbi1yZXF1ZXN0LW9uLXN1Ym1pdCJdLCJzb3VyY2VzIjp7IlNlcnZpY2VGYW1pbHkiOiIyIiwiU2VydmljZSI6IjciLCJTZXJ2aWNlU3ViY2F0ZWdvcnkiOiI1In19&exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsFormPath: 'objectform-ticket-create-5c48332d11a57',\n\t\t\t\t\t\t\t\tsFieldId: 'contacts_list',\n\t\t\t\t\t\t\t\taObjectIdsToIgnore : aObjectIdsToIgnore\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfunction(sResponseText, sStatus, oXHR){\n\t\t\t\t\t\t\t \/\/ Hiding modal in case of error as the general AJAX error handler will display a message\n\t\t\t\t\t\t\t if(sStatus === 'error')\n\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t oModalElem.modal('hide');\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t\toModalElem.modal('show');\n\t\t\t\t\t});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"org_id":{"id":"org_id","html":"<div class=\"form-group form_group_small\"><input type=\"hidden\" id=\"field_org_id_5c48332d556ff\" name=\"org_id\" value=\"220\" class=\"form-control\" \/><\/div>","js_inline":"","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"request_type":{"id":"request_type","html":"<div class=\"form-group form_group_small\"><input type=\"hidden\" id=\"field_request_type_5c48332d57d74\" name=\"request_type\" value=\"\" class=\"form-control\" \/><\/div>","js_inline":" \t\t\t\t\t$(\"[data-field-id='request_type'][data-form-path='objectform-ticket-create-5c48332d11a57']\").portal_form_field({\"validators\":{\"mandatory\":{\"reg_exp\":\".*\\\\S.*\",\"message\":\"Veuillez remplir ce champ\"}}});\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]},"attachments_for_form_objectform-ticket-create-5c48332d11a57":{"id":"attachments_for_form_objectform-ticket-create-5c48332d11a57","html":"<div class=\"form-group\"><div class=\"form_field_label\"><label for=\"field_attachments_for_form_objectform-ticket-create-5c48332d11a57_5c48332d5a3ff\" class=\"control-label\">Pièces jointes<\/label><\/div><div class=\"form_field_control\"><div class=\"help-block\"><\/div><div class=\"fileupload_field_content\"><div class=\"attachments_container row\"><\/div><div class=\"upload_container row\">Ajouter une pi\u00e8ce jointe: <input type=\"file\" id=\"field_attachments_for_form_objectform-ticket-create-5c48332d11a57_5c48332d5a3ff\" name=\"attachments_for_form_objectform-ticket-create-5c48332d11a57\" \/><span class=\"loader glyphicon glyphicon-refresh\"><\/span>(Taille de fichier max.: 24.00 Mb)<\/div><\/div><\/div><\/div>","js_inline":" \t\t\tvar RemoveAttachment = function(sAttId)\n\t\t\t{\n\t\t\t\t$('#attachment_' + sAttId).attr('name', 'removed_attachments[]');\n\t\t\t\t$('#display_attachment_' + sAttId).hide();\n\t\t\t};\n\n\t\t\t$('#field_attachments_for_form_objectform-ticket-create-5c48332d11a57_5c48332d5a3ff').fileupload({\n\t\t\t\turl: '\/pages\/exec.php\/object\/attachment\/add?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal',\n\t\t\t\tformData: { operation: 'add', temp_id: '1sgctap661qgcflo8hgta6v0av_0072506001548235565', object_class: 'Informatique', 'field_name': 'attachments_for_form_objectform-ticket-create-5c48332d11a57' },\n\t\t\t\tdataType: 'json',\n\t\t\t\tpasteZone: null, \/\/ Don't accept files via Chrome's copy\/paste\n\t\t\t\tdone: function (e, data) {\n\t\t\t\t\tif((data.result.error !== undefined) && window.console)\n\t\t\t\t\t{\n\t\t\t\t\t\tconsole.log(data.result.error);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar sDownloadLink = '\/pages\/exec.php\/object\/attachment\/download\/-sAttachmentId-?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal'.replace(\/-sAttachmentId-\/, data.result.att_id);\n\n\t\t\t\t\t\t$(this).closest('.fileupload_field_content').find('.attachments_container').append(\n\t\t\t\t\t\t\t'<div class=\"attachment col-xs-6 col-sm-3 col-md-2\" id=\"display_attachment_'+data.result.att_id+'\">'+\n\t\t\t\t\t\t\t'\t<a data-preview=\"'+data.result.preview+'\" href=\"'+sDownloadLink+'\" title=\"'+data.result.msg+'\">'+\n\t\t\t\t\t\t\t'\t\t<div class=\"attachment_icon\"><img src=\"'+data.result.icon+'\"><\/div>'+\n\t\t\t\t\t\t\t'\t\t<div class=\"attachment_name\">'+data.result.msg+'<\/div>'+\n\t\t\t\t\t\t\t'\t\t<input id=\"attachment_'+data.result.att_id+'\" type=\"hidden\" name=\"attachments[]\" value=\"'+data.result.att_id+'\"\/>'+\n\t\t\t\t\t\t\t'\t<\/a>'+\n\t\t\t\t\t\t\t'\t<input type=\"button\" class=\"btn btn-xs btn-danger hidden\" value=\"Supprimer\"\/>'+\n\t\t\t\t\t\t\t'<\/div>'\n\t\t\t\t\t\t);\n\t\t\t\t\t\t\/\/ Preview tooltip\n\t\t\t\t\t\tif(data.result.preview){\n\t\t\t\t\t\t\t$('#display_attachment_'+data.result.att_id).tooltip({\n\t\t\t\t\t\t\t\thtml: true,\n\t\t\t\t\t\t\t\ttitle: function(){ return '<img src=\"'+sDownloadLink+'\" style=\"max-width: 100%;\" \/>'; }\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\/\/ Showing remove button on hover\n\t\t\t\t\t\t$('#display_attachment_'+data.result.att_id).hover( function(){\n\t\t\t\t\t\t\t$(this).children(':button').toggleClass('hidden');\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\/\/ Remove button handler\n\t\t\t\t\t\t$('#display_attachment_'+data.result.att_id+' :button').click(function(oEvent){\n\t\t\t\t\t\t\toEvent.preventDefault();\n\t\t\t\t\t\t\tRemoveAttachment(data.result.att_id);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tstart: function() {\n\t\t\t\t\t\/\/ Scrolling to dropzone so the user can see that attachments are uploaded\n\t\t\t\t\t$(this)[0].scrollIntoView();\n\t\t\t\t\t\/\/ Showing loader\n\t\t\t\t\t$(this).closest('.upload_container').find('.loader').css('visibility', 'visible');\n\t\t\t\t},\n\t\t\t\tstop: function() {\n\t\t\t\t\t\/\/ Hiding the loader\n\t\t\t\t\t$(this).closest('.upload_container').find('.loader').css('visibility', 'hidden');\n\t\t\t\t\t\/\/ Adding this field to the touched fields of the field set so the cancel event is called if necessary\n\t\t\t\t\t$(this).closest(\".field_set\").trigger(\"field_change\", {\n\t\t\t\t\t\tid: 'field_attachments_for_form_objectform-ticket-create-5c48332d11a57_5c48332d5a3ff',\n\t\t\t\t\t\tname: 'attachments_for_form_objectform-ticket-create-5c48332d11a57'\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t\/\/ Preview tooltip\n\t\t\t$('.attachment [data-preview=\"true\"]').each(function(iIndex, oElem){\n\t\t\t\t$(oElem).parent().tooltip({\n\t\t\t\t\thtml: true,\n\t\t\t\t\ttitle: function(){ return '<img src=\"'+$(oElem).attr('href')+'\" style=\"max-width: 100%;\" \/>'; }\n\t\t\t\t});\n\t\t\t});\n\t\t\t\/\/ Remove button handler\n\t\t\t$('.attachments_container .attachment :button').click(function(oEvent){\n\t\t\t\toEvent.preventDefault();\n\t\t\t\tRemoveAttachment($(this).closest('.attachment').find(':input[name=\"attachments[]\"]').val());\n\t\t\t});\n\t\t\t\/\/ Remove button showing\n\t\t\tif(true)\n\t\t\t{\n\t\t\t\t$('.attachment').hover( function(){\n\t\t\t\t\t$(this).find(':button').toggleClass('hidden');\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t\/\/ Handles a drag \/ drop overlay\n\t\t\tif($('#drag_overlay').length === 0)\n\t\t\t{\n\t\t\t\t$('body').append( $('<div id=\"drag_overlay\" class=\"global_overlay\"><div class=\"overlay_content\"><div class=\"content_uploader\"><div class=\"icon glyphicon glyphicon-cloud-upload\"><\/div><div class=\"message\">D\u00e9posez vos fichiers pour les ajouter en pi\u00e8ces jointes<\/div><\/div><\/div><\/div>') );\n\t\t\t}\n\n\t\t\t\/\/ Handles highlighting of the drop zone\n\t\t\t\/\/ Note : This is inspired by itop-attachments\/main.attachments.php\n\t\t\t$(document).on('dragover', function(oEvent){\n\t\t\t\tvar bFiles = false;\n\t\t\t\tif (oEvent.dataTransfer && oEvent.dataTransfer.types)\n\t\t\t\t{\n\t\t\t\t\tfor (var i = 0; i < oEvent.dataTransfer.types.length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (oEvent.dataTransfer.types[i] == \"application\/x-moz-nativeimage\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbFiles = false; \/\/ mozilla contains \"Files\" in the types list when dragging images inside the page, but it also contains \"application\/x-moz-nativeimage\" before\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (oEvent.dataTransfer.types[i] == \"Files\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbFiles = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!bFiles) return; \/\/ Not dragging files\n\n\t\t\t\tvar oDropZone = $('#drag_overlay');\n\t\t\t\tvar oTimeout = window.dropZoneTimeout;\n\t\t\t\t\/\/ This is to detect when there is no drag over because there is no \"drag out\" event\n\t\t\t\tif (!oTimeout) {\n\t\t\t\t\toDropZone.removeClass('drag_out').addClass('drag_in');\n\t\t\t\t} else {\n\t\t\t\t\tclearTimeout(oTimeout);\n\t\t\t\t}\n\t\t\t\twindow.dropZoneTimeout = setTimeout(function () {\n\t\t\t\t\twindow.dropZoneTimeout = null;\n\t\t\t\t\toDropZone.removeClass('drag_in').addClass('drag_out');\n\t\t\t\t}, 200);\n\t\t\t});\n\n","css_inline":"","js_files":[],"css_files":[],"css_classes":["form_field_cosy"]}}});//Formhandlerdeclaration$('#objectform-ticket-create-5c48332d11a57').portal_form_handler({formmanager_class:"Combodo\x5CiTop\x5CPortal\x5CForm\x5CObjectFormManager",formmanager_data:{"id":"objectform-ticket-create-5c48332d11a57","transaction_id":"0072506001548235565","formmanager_class":"Combodo\\iTop\\Portal\\Form\\ObjectFormManager","formrenderer_class":"Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer","formrenderer_endpoint":"\/pages\/exec.php\/object\/create\/Informatique?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal","formobject_class":"Informatique","formmode":"create","formactionrulestoken":"eyJydWxlcyI6WyJjb250YWN0LXRvLXVzZXJyZXF1ZXN0Iiwic2VydmljZXN1YmNhdGVnb3J5LXRvLXVzZXJyZXF1ZXN0IiwiZ28tdG8tb3Blbi1yZXF1ZXN0LW9uLXN1Ym1pdCJdLCJzb3VyY2VzIjp7IlNlcnZpY2VGYW1pbHkiOiIyIiwiU2VydmljZSI6IjciLCJTZXJ2aWNlU3ViY2F0ZWdvcnkiOiI1In19","formproperties":{"id":"ticket-create","type":"custom_list","properties":{"display_mode":"cosy","always_show_submit":true},"fields":[],"layout":{"type":"xhtml","content":" <div class=\"row\">\n <div class=\"col-sm-6\">\n <div class=\"form_field\" data-field-id=\"service_id\" data-field-flags=\"mandatory\">\n\t\t\t\t\t\t\t\t<\/div>\n <\/div>\n <div class=\"col-sm-6\">\n <div class=\"form_field\" data-field-id=\"servicesubcategory_id\" data-field-flags=\"mandatory\">\n\t\t\t\t\t\t\t\t<\/div>\n <\/div>\n <\/div>\n <div id=\"service_details_placeholder\">\n\t\t\t\t\t\t<\/div>\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <div class=\"form_field\" data-field-id=\"impact\">\n\t\t\t\t\t\t\t\t<\/div>\n <\/div>\n <div class=\"col-sm-6\">\n <div class=\"form_field\" data-field-id=\"urgency\">\n\t\t\t\t\t\t\t\t<\/div>\n <\/div>\n <\/div>\n <div>\n <div class=\"form_field\" data-field-id=\"title\">\n\t\t\t\t\t\t\t<\/div>\n <div class=\"form_field\" data-field-id=\"description\">\n\t\t\t\t\t\t\t<\/div>\n <div class=\"form_field\" data-field-id=\"contacts_list\">\n\t\t\t\t\t\t\t<\/div>\n <\/div>"}}},field_set:oFieldSet_objectformticketcreate5c48332d11a57,submit_btn_selector:$('#objectform-ticket-create-5c48332d11a57').parent().find('.form_btn_submit, .form_btn_transition'),cancel_btn_selector:$('#objectform-ticket-create-5c48332d11a57').parent().find('.form_btn_cancel'),submit_url:"/pages/exec.php/manage/ongoing-tickets-for-portal-user?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal",cancel_url:null,endpoint:"/pages/exec.php/object/create/Informatique?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal",is_modal:true});//Stickybuttonshandlerif($('#objectform-ticket-create-5c48332d11a57 .form_btn_regular button').length>0){//Note:Thispatterniftopreventperformanceissues//-CloningbuttonsvaroNormalRegularButtons_objectformticketcreate5c48332d11a57=$('#objectform-ticket-create-5c48332d11a57 .form_btn_regular');varoStickyRegularButtons_objectformticketcreate5c48332d11a57=oNormalRegularButtons_objectformticketcreate5c48332d11a57.clone(true,true);oStickyRegularButtons_objectformticketcreate5c48332d11a57.addClass('sticky');if(oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_submit span.glyphicon').length>0){oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_submit').html(oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_submit span.glyphicon')[0].outerHTML);}if(oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_cancel span.glyphicon').length>0){oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_cancel').html(oStickyRegularButtons_objectformticketcreate5c48332d11a57.find('.form_btn_cancel span.glyphicon')[0].outerHTML);}$('#objectform-ticket-create-5c48332d11a57').closest('.modal').append(oStickyRegularButtons_objectformticketcreate5c48332d11a57);//-GlobaltimeoutforanyvaroScrollTimeout;//-ScrollhandlerscrollHandler_objectformticketcreate5c48332d11a57=function(){if($('#objectform-ticket-create-5c48332d11a57 .form_buttons').visible()){oStickyRegularButtons_objectformticketcreate5c48332d11a57.addClass('closed');}else{oStickyRegularButtons_objectformticketcreate5c48332d11a57.removeClass('closed');}};//-Eventbindingforscroll$('.modal.in').off('scroll').on('scroll',function(){if(oScrollTimeout){//Clearthetimeout,ifoneispendingclearTimeout(oScrollTimeout);oScrollTimeout=null;}oScrollTimeout=setTimeout(scrollHandler_objectformticketcreate5c48332d11a57,50);});//-Eventbindingforlinkedsetcollapse$('.modal.in').off('shown.bs.collapse hidden.bs.collapse').on('shown.bs.collapse hidden.bs.collapse',function(){scrollHandler_objectformticketcreate5c48332d11a57();});//-Eventbindingforformbuilding/updating//Note:Wedonotwantto'off'theeventoritwillremovelistenersfromthewidgetoFieldSet_objectformticketcreate5c48332d11a57.on('form_built',function(oEvent){scrollHandler_objectformticketcreate5c48332d11a57();});//-InitialtestsetTimeout(function(){scrollHandler_objectformticketcreate5c48332d11a57();},400);//Removestickybuttonwhenclosingmodal$('#objectform-ticket-create-5c48332d11a57').closest('.modal').on('hide.bs.modal',function(){oStickyRegularButtons_objectformticketcreate5c48332d11a57.remove();});}//Scrolltop(becausesometimeswhenseveralmodalshavebeenopened)$('#objectform-ticket-create-5c48332d11a57').closest('.modal').scrollTop(0);$('#objectform-ticket-create-5c48332d11a57').closest('.modal').find('.modal-footer').hide();});
Thanks for your help Pierre !
Regards,
Rafael.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
Using your browser console check the ajax POST request that is triggered when clicking the submit button : there might be a server side error.
Also check you log/error.log ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Many many thanks to help me !
There no error message in the error.log file.
I can see the dedicated form (with POST action) in the client side code but I don't know how check the ajax POST request ?
Could you please explain to me the way of doing it ?
Regards,
Rafael.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is not the right http query, see again my capture : you should find the POST request.
This request should be done to a path like this one : /pages/exec.php/object/create/UserRequest?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think the POST entry you want me to give you is generated after I submit the form. Isn't it?
In my situation, I can see the "save" button but click on it does not do anything. So impossible for me to submit the form.
It is just as if the client code is inactive to initiate the Ajax request...
As you can see in the screenshot above, the only requests I can see in the console concern the first load of the empty form in order to create the Ticket.
I wish I'm clear enough... And I don't know where I can have a look to understand what is not working.
Thank you to help me.
Regards,
Rafael.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To complete the idea in my previous post, I can submit the form by clicking on "Cancel" button (it works !) and then I can see a POST request in the console (See in attach).
Only the "Save" button does not do anything.
I have a single extension that I have installed on different "blank" instances of iTop :
* 2.5 with simple Ticket management
* 2.5 with compliant ITIL Ticket management
* 2.6 with compliant ITIL Ticket management
* 2.6 with compliant ITIL Ticket management + ITIL Change Management
The result is always the same.
I just installed a new instance of iTop (2.6.0). The creation of the Ticket works fine.
Before adding my extension, I save the source code of the page.
After adding my extension, creation of the Ticket doesn't work and the main difference I can see between the 2 codes concerns the following instruction :
Before customization : "factory":{"type":"class","value":"UserRequest"}
After customization : "factory":{"type":"method","value":"\\Ticket::CreateFromServiceSubcategory"}
Is there an error in this instruction ?
Thanks for your help !
Regards,
Rafael.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm still having question about the way of customizing the Portal for managing new types of Tickets.
What I want to do :
In my company, we need to manage different type of Tickets. So I created subclass A, B and C of Ticket's class.
Each Service / Sub Category of Service is linked to one of theses classes.
What I done :
1. I redefined the class ServiceSubcategory to modify the request_type field :
When I try to create a new Ticket in Portal : I select a Service / Subcategory of Service (linked to A subclass of Ticket), I fill the form and I have the following error message :
Where have I made a mistake?
Thanks for your help !
Regards,
Rafael.
Last edit: Rafael AINCIART 2018-12-20
Sorry, I complete my message. I also modified the scopes of Ticket :
Any idea about my issue ?
- I created new classes as childs of Ticket class
- I redefined the class ServiceSubcategory to modify the request_type field
- I overload the method Ticket::CreateFromServiceSubcategory() in Ticket class to link the new request to the right class
- I modify the scopes in Portal to allow the new class instead of UserRequest and Incident
But a new request still point to UserRequest type...
Something must be missing.
Rafael.
Hi Rafael,
Can you share with us the compiled portal definition? (Located under /env-production/core/module_designs/itop-portal.xml)
Hi Guillaume,
With great pleasure ! Thanks to help me :)
Great, so I think the problem is in your
services
brick. It defines that all created objects will beUserRequest
. See line 130:You need to change this so your PHP method is called. Replace the line above by:
Mind the backslash before the class and the omission of parenthesis at the end
You can find an example of this in the
datamodels/2.x/itop-full-itil/datamodel.itop-full-itil.xml
file. FYI, if you had choosen the ITIL Request management and ITIL Change management options during the setup, this would already be done.Hope it helps!
Ok Guillaume ! I test it now and I give you my feedback !
Hi Guillaume !
It is several weeks now since I try to customize itop Portal to manage new types of Tickets but I don't understand why it's not working...
1. I created new classes as childs of Ticket class
2. I redefined the class ServiceSubcategory to modify the request_type field
3. I overload the method Ticket::CreateFromServiceSubcategory() in Ticket class to link the new request to the right class
4. I modify the scopes in Portal to allow the new class instead of UserRequest and Incident
5. I give the appropriates rights on the new classes for the Portal users
When I execute the Portal and try to create a new Ticket (with one of the new type), the form appears but it's impossible to submit it. No error message, nothing happend. It is as if the javacript code to execute the ajax request is missing.
I have installed a new instance of itop with the full itil management (but without change management) but the result is still the same.
In debug mode (netbeans-xdebug), I have no error : the CreateFromServiceSubcategory($oServiceSubcategory) function is called and a new class is created. But impossible to save the form.
In CreateFromServiceSubcategory(), I have set the request_type property to the correct value :
print_r($oRet, true) give the folowing result :
[With A a sub-class of Ticket and a copy of UserRequest]
I have no idea about how to continue my investigation.
Thank you to help me.
Regards,
Rafael.
Last edit: Rafael AINCIART 2019-01-21
Hello,
What do you mean by '"the form appears but it's impossible to submit it" ?
Are the buttons present at the end of the form dialog ?
If yes, do you see any JS error in your browser console ?
Hi Pierre !
The modal window of the form is normally loaded and, in the code, the corresponding object is created.
I can see the buttons to save the new Ticket in the bottom of the form.
The only problem is that I can't save the form : there is no result when I click on the "Apply" button (but it works on the "Cancel" one).
I have no error message (even if I add the debug=true in the url).
I use the chrome console to inspect the client side code but I don't see what can be wrong...
The error messages I can see :
* GET http://prh2.localhost/env-production/fonts/glyphicons-halflings-regular.woff2 net::ERR_ABORTED 404 (Not Found)
* GET http://prh2.localhost/env-production/fonts/glyphicons-halflings-regular.woff net::ERR_ABORTED 404 (Not Found)
The script executed by the button :
Thanks for your help Pierre !
Regards,
Rafael.
Hi !
Anyone to help me ?
Could it be a bug and should I open a ticket for this issue ?
Thanks for your answers !
Regards,
Rafael.
Hello,
Using your browser console check the ajax POST request that is triggered when clicking the submit button : there might be a server side error.
Also check you log/error.log ?
Hi Pierre !
Many many thanks to help me !
There no error message in the error.log file.
I can see the dedicated form (with POST action) in the client side code but I don't know how check the ajax POST request ?
Could you please explain to me the way of doing it ?
Regards,
Rafael.
Yes, I meant the POST return value.
Attached is an example in Firefox
Pierre,
The header tab :
And the Response tab :
This is not the right http query, see again my capture : you should find the POST request.
This request should be done to a path like this one : /pages/exec.php/object/create/UserRequest?exec_module=itop-portal-base&exec_page=index.php&portal_id=itop-portal
Hi Pierre !
Sorry, I was using Chrome and the dev tool is not exactly the same.
I just installed Firefow and I have the good interface as you show me.
Please see the result in attach. The problem for me is that all the request are in GET method...
Thank you !
Pierre,
I think the POST entry you want me to give you is generated after I submit the form. Isn't it?
In my situation, I can see the "save" button but click on it does not do anything. So impossible for me to submit the form.
It is just as if the client code is inactive to initiate the Ajax request...
As you can see in the screenshot above, the only requests I can see in the console concern the first load of the empty form in order to create the Ticket.
I wish I'm clear enough... And I don't know where I can have a look to understand what is not working.
Thank you to help me.
Regards,
Rafael.
To complete the idea in my previous post, I can submit the form by clicking on "Cancel" button (it works !) and then I can see a POST request in the console (See in attach).
Only the "Save" button does not do anything.
Hello,
It is !
So something isn't working in the JavaScript that is triggered when clicking the button... But you said there was no JS error...
Someone needs to debug...
Try to create a package that reproduce the error on a "blank" iTop ?
Hi Pierre,
I have a single extension that I have installed on different "blank" instances of iTop :
* 2.5 with simple Ticket management
* 2.5 with compliant ITIL Ticket management
* 2.6 with compliant ITIL Ticket management
* 2.6 with compliant ITIL Ticket management + ITIL Change Management
The result is always the same.
Please find this extension in attach.
Hope it helps !
Rafael.
Pierre, Guillaume,
Would you have any magic idea to go further on analysis?
I still do not understand..., but I live in hope that a solution exists ;)
Regards,
Rafael.
Hi again,
Ok, Google is my friend ;)
In the developer console > Network tab > XHR :
When I load the form I can see the following messages
Il fill the form and I click on the submit button : nothing...
Does it helps ?
Regards,
Rafael.
Supplement to the reply (Response tab content) :
I just installed a new instance of iTop (2.6.0). The creation of the Ticket works fine.
Before adding my extension, I save the source code of the page.
After adding my extension, creation of the Ticket doesn't work and the main difference I can see between the 2 codes concerns the following instruction :
Before customization :
"factory":{"type":"class","value":"UserRequest"}
After customization :
"factory":{"type":"method","value":"\\Ticket::CreateFromServiceSubcategory"}
Is there an error in this instruction ?
Thanks for your help !
Regards,
Rafael.