Vue - Dynamic Dialogs with different Classes

Vue also bound to SVG elements

by Ben Clayton

HTML

<script type="text/x-template" id="rect-svg-template">
		<g>
			<rect @click="rectClick" :x="rectX()" :y="rectY()" :width="rectWidth()" :height="rectHeight()" :fill="rectFill()" stroke-width="1" />
			<text :x="textX()" :y="textY()" fill="black">{{ name() }}</text>
		</g>
</script>

<script type="text/x-template" id="circle-svg-template">
		<g>
			<circle @click="circleClick" :cx="circleX()" :cy="circleY()" :r="circleRadius()" :stroke="circleStroke()" :fill="circleFill()" stroke-width="1" />
			<text :x="textX()" :y="textY()" fill="black">{{ name() }}</text>
		</g>
</script>

	<!-- Property template -->
	<script type="text/x-template" id="circle-dialog-template">
		<div class='dialog'>
			<div @click="close" class="closebtn">X</div>
			
			<div class="proplist">
			<h5>Circle</h5>
				<table>
					<tr>
						<td class='label'><label>Name:</label></td>
						<td class='value'><input v-model='name'></td>
					</tr>
					<tr>
						<td class='label'><label>Size:</label></td>
						<td class='value'><input type='range' v-model='size' min='0' max='100'>{{ size }}</td>
					</tr>
					<tr>
						<td class='label'><label>X:</label></td>
						<td class='value'><input type='range' v-model='x' min='100' max='400'>{{ x }}</td>
					</tr>
					<tr>
						<td class='label'><label>Y:</label></td>
						<td class='value'><input type='range' v-model='y' min='50' max='250'>{{ y }}</td>
					</tr>
					
					<tr>
						<td class='label'><label>Color:</label></td>
						<td class='value'>
							<my-color-selector  :param="$data.getPropByRef('color')"></my-color-selector>
						</td>
					</tr>
				</table>
			</div>
		</div>
	</script>
	
	<script type="text/x-template" id="rect-dialog-template">
		<div class='dialog'>
			<div @click="close" class="closebtn">X</div>
			
			<div class="proplist">
			<h5>Rectangle</h5>
				<table>
					<tr>
						<td class='label'><label>Name:</label></td>
						<td class='value'><input v-model='name'></td>
					</tr>
					<tr>
						<td...

CSS

.dialogouter {
			display: inline-block;
			margin: 20px;
		}
		
		.dialog {
			width: 240px;
			height: 300px;
			display: inline-block;
			border: 1px solid gray;
			
		}
		.dialog .proplist {		
			padding: 10px;
		}
		.dialog table td.label {}
		
		.dialog table td.value {
			min-width: 180px;
		}
		.dialog .closebtn {
			float: right;
			border:1px solid gray;
		}

JavaScript

class myclass_circle{
			constructor( name, color, size, x, y ) {
				this.type = 'circle';
				this.name = name || "mycircle";
				this.size = size || 20;
				this.color = color || "gray";
				this.x = x || 260;
				this.y = y || 100; 
			}
			
			getPropByRef( nm ){ // used to pass 'color' by ref to color selector component
				return { ref : this, prop: nm };
			}

			getSVGViewData(){
				return { ref:this, x:this.x, y:this.y, size:this.size, name:this.name, color:this.color, click:this.click, close:this.close };
			}

			propertyTemplate(){
				return "#circle-dialog-template";
			}
			close(ptr){
				alert("close circle dialog");
				pd.deleteDialog(ptr);
			}
			
			// The click is not called with the context of the class
			//  but the parameter 'cls' points at this class.
			click(ptr ){
				// 'pd' is a global pointer to the view handling the dialogs array.
				pd.singleDialog(ptr);
			}
		
		}
		class myclass_rect{
			constructor( name, color,width,height, x, y ) {
				this.type = 'rect';
				this.name = name || "mycircle";
				this.width = width || 20;
				this.height = height || 20;
				this.color = color || "gray";
				this.x = x || 260;
				this.y = y || 100; 
			}
			
			getPropByRef( nm ){ // used to pass 'color' by ref to color selector component
				return { ref : this, prop: nm };
			}

			getSVGViewData(){
				return { ref:this, x:this.x, y:this.y, width:this.width, height:this.height, name:this.name, color:this.color, click:this.click };
			}

			propertyTemplate(){
				return "#rect-dialog-template";
			}
			close(ptr){
				alert("close rect dialog");
				pd.deleteDialog(ptr);
			}
			// The click is not called with the context of the class
			//  but the parameter 'cls' points at this class.
			click( ptr ){
				// 'pd' is a global pointer to the view handling the dialogs array.
				pd.singleDialog(ptr);
			}
		
		}

		var objarray = [
				new myclass_circle("C1","red",10,100,100),
				new myclass_circle("C2","blue",10,160,100),
				new...