Просмотр исходного кода

N°579: Creating an object with the [+] button on external key pointing to an abstract class.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@4838 a333f486-631f-4898-b8df-5754b55c2be0
glajarige 8 лет назад
Родитель
Сommit
7f516f02df
3 измененных файлов с 99 добавлено и 21 удалено
  1. 47 3
      application/ui.extkeywidget.class.inc.php
  2. 28 3
      js/extkeywidget.js
  3. 24 15
      pages/ajax.render.php

+ 47 - 3
application/ui.extkeywidget.class.inc.php

@@ -111,7 +111,7 @@ class UIExtKeyWidget
 		$oPage->add_linked_script('../js/extkeywidget.js');
 		$oPage->add_linked_script('../js/forms-json-utils.js');
 		
-		$bCreate = (!$this->bSearchMode) && (!MetaModel::IsAbstract($this->sTargetClass)) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
+		$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
 		$bExtensions = true;
 		$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
 		$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
@@ -298,7 +298,9 @@ EOF
 		}
 		if ($bCreate && $bExtensions)
 		{
-			$sHTMLValue .= "<span class=\"field_input_btn\"><img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/></span>";
+			$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
+
+			$sHTMLValue .= "<span class=\"field_input_btn\"><img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"/></span>";
 			$oPage->add_ready_script(
 <<<EOF
 		if ($('#ajax_{$this->iId}').length == 0)
@@ -424,7 +426,49 @@ EOF
 			return '';
 		}
 	}
-	
+
+    /**
+	 * Get the form to select a leaf class from the $this->sTargetClass (that should be abstract)
+	 * Note: Inspired from UILinksWidgetDirect::GetObjectCreationDialog()
+	 *
+     * @param WebPage $oPage
+     */
+	public function GetClassSelectionForm(WebPage $oPage)
+	{
+        // For security reasons: check that the "proposed" class is actually a subclass of the linked class
+        // and that the current user is allowed to create objects of this class
+        $aSubClasses = MetaModel::EnumChildClasses($this->sTargetClass);
+        $aPossibleClasses = array();
+        foreach($aSubClasses as $sCandidateClass)
+        {
+            if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
+            {
+                $aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
+            }
+        }
+
+        $sDialogTitle = '';
+        $oPage->add('<div id="ac_create_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div id="dcr_'.$this->iId.'">');
+        $oPage->add('<form>');
+
+		$sClassLabel = MetaModel::GetName($this->sTargetClass);
+		$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
+		$oPage->add('<nobr><select name="class">');
+		asort($aPossibleClasses);
+		foreach($aPossibleClasses as $sClassName => $sClassLabel)
+		{
+			$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
+		}
+		$oPage->add('</select>');
+		$oPage->add('&nbsp; <button type="submit" class="action" style="margin-top:15px;"><span>' . Dict::S('UI:Button:Ok') . '</span></button></nobr></p>');
+
+        $oPage->add('</form>');
+        $oPage->add('</div></div></div>');
+        $oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
+        $oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
+        $oPage->add_ready_script("$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoSelectObjectClass);");
+	}
+
 	/**
 	 * Get the form to create a new object of the 'target' class
 	 */

+ 28 - 3
js/extkeywidget.js

@@ -18,6 +18,7 @@
 function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper, sAttCode, bSearchMode)
 {
 	this.id = id;
+	this.sOriginalTargetClass = sTargetClass;
 	this.sTargetClass = sTargetClass;
 	this.sFilter = sFilter;
 	this.sTitle = sTitle;
@@ -275,7 +276,31 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		$('#label_'+me.id).focus();
 		me.ajax_request = null;
 	};
-	
+
+	this.SelectObjectClass = function(oWizHelper)
+	{
+        // Resetting target class to its original value
+        // (If not done, closing the dialog and trying to create a object again
+        // will force it be of the same class as the previous call)
+        me.sTargetClass = me.sOriginalTargetClass;
+
+        me.CreateObject(oWizHelper);
+	};
+
+	this.DoSelectObjectClass = function()
+	{
+		// Retrieving selected value
+		var oSelectedClass = $('#ac_create_'+me.id+' select');
+		if(oSelectedClass.length !== 1) return;
+
+		// Setting new target class
+		me.sTargetClass = oSelectedClass.val();
+
+		// Opening real creation form
+        $('#ac_create_'+me.id).dialog('close');
+		me.CreateObject();
+	};
+
 	this.CreateObject = function(oWizHelper)
 	{
 		if($('#'+me.id).attr('disabled')) return; // Disabled, do nothing
@@ -326,7 +351,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 	
 	this.CloseCreateObject = function()
 	{
-		$('#ac_create_'+me.id).dialog( "close" );
+		$('#ac_create_'+me.id).dialog( "close" );console.log('closecreateobj')
 	};
 	
 	this.OnCloseCreateObject = function()
@@ -342,7 +367,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		$('#label_'+me.id).focus();
 		$('#ac_create_'+me.id).dialog("destroy");
 		$('#ac_create_'+me.id).remove();
-		$('#ajax_'+me.id).html('');
+		$('#ajax_'+me.id).html('');console.log('onclosecreateobj')
 	};
 	
 	this.DoCreateObject = function()

+ 24 - 15
pages/ajax.render.php

@@ -454,22 +454,31 @@ try
 		// ui.extkeywidget
 		case 'objectCreationForm':
 		$oPage->SetContentType('text/html');
+		// Retrieving parameters
 		$sTargetClass = utils::ReadParam('sTargetClass', '', false, 'class');
-		$iInputId = utils::ReadParam('iInputId', '');
-		$sAttCode = utils::ReadParam('sAttCode', '');
-		$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, false);
-		$sJson = utils::ReadParam('json', '', false, 'raw_data');
-		if (!empty($sJson))
-		{
-			$oWizardHelper = WizardHelper::FromJSON($sJson);
-			$oObj = $oWizardHelper->GetTargetObject();
-		}
-		else
-		{
-			// Search form: no current object
-			$oObj = null;
-		}
-		$oWidget->GetObjectCreationForm($oPage, $oObj);
+        $iInputId = utils::ReadParam('iInputId', '');
+        $sAttCode = utils::ReadParam('sAttCode', '');
+        $sJson = utils::ReadParam('json', '', false, 'raw_data');
+		// Building form, if target class is abstract we ask the user for the desired leaf class
+        $oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, false);
+        if(MetaModel::IsAbstract($sTargetClass))
+        {
+            $oWidget->GetClassSelectionForm($oPage);
+        }
+        else
+        {
+            if (!empty($sJson))
+            {
+                $oWizardHelper = WizardHelper::FromJSON($sJson);
+                $oObj = $oWizardHelper->GetTargetObject();
+            }
+            else
+            {
+                // Search form: no current object
+                $oObj = null;
+            }
+            $oWidget->GetObjectCreationForm($oPage, $oObj);
+        }
 		break;
 		
 		// ui.extkeywidget