# Creating, Deleting and Modifying Elements

In this chapter, we're going to learn how to create and modify elements. The most important is that you **should not** create or modify elements directly like `var class1 = new UMLClass()` or `class1.name = "New Name"` because all changes should be done via *operations* which supports by undo and redo.

## Creating elements

### Creating a model element

You can call `createModel` function of `app.factory` to create a model element with an option object.

The option object may have following fields:

* `id` : ID of factory function to create an element. To see the full ID list, execute `app.factory.getModelIds()`.
* `parent` : A parent element where the created element to be contained.
* `field` (optional) : Field name of the parent element (default is `ownedElements`).
* `modelInitializer` (optional) : A function to initialize the created model element.

```javascript
// Get a reference to top-level project
var project = app.repository.select("@Project")[0]

// Create a UMLModel element as a child of project
var model1 = app.factory.createModel({ id: "UMLModel", parent: project })

// Create a UMLClass element as a child of the model
var class1 = app.factory.createModel({ id: "UMLClass", parent: model1 })

// Create a UMLAttribute element and add to the field 'attributes' of the class
var attr1 = app.factory.createModel({ id: "UMLAttribute", parent: class1, field: "attributes" })

// Create a UMLClass with options
var options = {
  id: "UMLClass",
  parent: model1,
  modelInitializer: function (elem) {
    elem.name = "MyClass";
    elem.isAbstract = true;
  }
}
var class2 = app.factory.createModel(options);
```

You can see the created elements in **Model Explorer** and undo and redo are available for each creation.

### Creating a diagram

Call `createDiagram` function of `app.factory` to create a diagram with an option object:

The option object may have following fields:

* `id` : ID of Factory function to create a diagram. To see the full ID list, execute `app.factory.getDiagramIds()`.
* `parent` : A parent element where the created diagram to be contained.
* `options` (optional) : An object containing the below options.
* `diagramInitializer` (optional) : A function to initialize the created diagram.

```javascript
// Get a reference to top-level project
var project = app.repository.select("@Project")[0]

// Create a UMLModel element as a child of project
var model1 = app.factory.createModel({ id: "UMLModel", parent: project })

// Create a UMLClassDiagram as a child of the model
var diagram1 = app.factory.createDiagram({ id: "UMLClassDiagram", parent: model1 })

// Create a UMLClassDiagram with options
var options = {
  id: "UMLClassDiagram",
  parent: model1,
  diagramInitializer: function (dgm) {
    dgm.name = "MyDiagram";
    dgm.defaultDiagram = true;
  }
}
var diagram2 = app.factory.createDiagram(options)
```

### Creating a model element and a view element at once

Call `createModelAndView` function of `app.factory` to create a model element and a view element at once with an option object.

The option object may have following fields:

* `id` : ID of Factory function. To see the full ID list, execute `Factory.getModelAndViewIds()`.
* `parent` : A parent element where the created model element to be contained.
* `diagram` : A diagram element where the created view element to be contained.
* `modelInitializer` (optional) : A function to initialize the created model element.
* `viewInitializer` (optional) : A function to initialize the created view element.
* `x1`, `y1`, `x2`, `y2` (optional) : Rectangle coordinate to initialize position and size of the created view element.
* `tailView`, `headView` (optional) : If you try to create a relationship (e.g. `UMLAssociation`), the created view element connects these two view elements `tailView` and `headView`.
* `tailModel`, and `headModel` (optional) : If you try to create a relationship, the created model element connects these two model elements `tailModel` and `headModel`.
* `containerView` (optional) : A view element where the created view element to be contained.

The function `createModelAndView` returns the created view element, so you need to get the create model element by accessing `model` field. (e.g. `classView1.model`). Following code will create two classes and a association connecting the two classes.

```javascript
// Create a UMLClass and UMLClassView
var options1 = {
  id: "UMLClass",
  parent: diagram1._parent,
  diagram: diagram1,
  x1: 100,
  y1: 100,
  x2: 200,
  y2: 200
}
var classView1 = app.factory.createModelAndView(options1)

// Create another UMLClass and UMLClassView
var options2 = {
  id: "UMLClass",
  parent: diagram1._parent,
  diagram: diagram1,
  x1: 400,
  y1: 100,
  x2: 500,
  y2: 200
}
var classView2 = app.factory.createModelAndView(options2)

// Create an association connecting the two classes
var options3 = {
  id: "UMLAssociation",
  parent: diagram1._parent,
  diagram: diagram1,
  tailView: classView1,
  headView: classView2,
  tailModel: classView1.model,
  headModel: classView2.model
}
var assoView = app.factory.createModelAndView(options3)
```

### Creating a view element of an existing model element

Call `createViewOf` function of `app.factory` to create a view element of an existing model element with an option object.

The option object may have following fields:

* `model` : A model element referenced by the created view element.
* `diagram` : A diagram element where the created view element to be contained.
* `viewInitializer` (optional) : A function to initialize the created view element.
* `x`, `y` (optional) : Position of the created view element.
* `containerView` (optional) : A view element where the created view element to be contained.

```javascript
var options = {
  model: classView1.model,
  diagram: diagram1,
  x: 500,
  y: 500,
}
app.factory.createViewOf(options)
```

You will see the one more class view element at (500, 500).

### Adding tags to an element

If you want to extend an element with additional tags, you can create tags by calling `createModel` function with `Tag` parameter of `app.factory`. There are five kinds of Tag: String, Number, Boolean, Reference, and Hidden. Hidden tags are not shown in diagrams, but other tags are shown as properties. (Check **Format > Show Property** menu). Following code will create a string tag to the selected element.

```javascript
// Get a selected element
var selected = app.selections.getSelected()

// Options for creating a tag
var options = {
  id: "Tag",
  parent: selected,
  field: "tags",
  modelInitializer: function (tag) {
    tag.name = "Tag1";
    tag.kind = type.Tag.TK_STRING; // or TK_BOOLEAN, TK_NUMBER, TK_REFERENCE, TK_HIDDEN
    tag.value = "String Value...";
    // tag.checked = true; // for TK_BOOLEAN
    // tag.number = 100; // for TK_NUMBER
    // tag.reference = ...; // for TK_REFERENCE
  }
}

// Create a tag to the selected element
var tag1 = app.factory.createModel(options)
```

## Deleting elements

To delete some elements, call `app.engine.deleteElements` function with model and view elements as arguments.

```javascript
// Delete selected model elements
var models = app.selections.getSelectedModels()
app.engine.deleteElements(models, [])

// Or, delete selected view elements
var views = app.selections.getSelectedViews()
app.engine.deleteElements([], views)

// Delete all selected model and view elements
var models = app.selections.getSelectedModels()
var views = app.selections.getSelectedViews()
app.engine.deleteElements(models, views)
```

## Modifying elements

### Change property value

You **should not** modify a property of an element directly like `class1.name = "New Name"` because all changes should be done via *operations* which supports by undo and redo.

To change property value, use `app.engine.setProperty()` function as below:

```javascript
// Get a selected element
var selected = app.selections.getSelected()
// Change property value
app.engine.setProperty(selected, 'name', 'New Name')
```

## Examples

### Sequence Diagram

Here is an example to create a Sequence Diagram including two Lifelines and a Message.

```javascript
var project = app.repository.select("@Project")[0]

var model1 = app.factory.createModel({ id: "UMLModel", parent: project })

// Create a Sequence Diagram
var options = {
  id: "UMLSequenceDiagram",
  parent: model1,
  diagramInitializer: function (dgm) {
    dgm.name = "MyDiagram";
  }
}
var diagram1 = app.factory.createDiagram(options)

// Create a Lifeline
var options1 = {
  id: "UMLLifeline",
  parent: diagram1._parent,
  diagram: diagram1,
  x1: 50,
  y1: 20,
  x2: 50,
  y2: 20
}
var lifelineView1 = app.factory.createModelAndView(options1)

// Create another Lifeline
var options2 = {
  id: "UMLLifeline",
  parent: diagram1._parent,
  diagram: diagram1,   
  x1: 150,
  y1: 20,
  x2: 150,
  y2: 20
}
var lifelineView2 = app.factory.createModelAndView(options2)

// Create a Message connecting the above two Lifelines
var options3 = {
  id: "UMLMessage",
  parent: diagram1._parent,
  diagram: diagram1, 
  x1: 50,
  y1: 100,
  x2: 150,
  y2: 100,
  tailView: lifelineView1,
  headView: lifelineView2,
  tailModel: lifelineView1.model,
  headModel: lifelineView2.model
}
var messageView1 = app.factory.createModelAndView(options3)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.staruml.io/v5/developing-extensions/creating-deleting-and-modifying-elements.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
