Nested tables generation

Hello,
I’d like to generate a rather complex table (nested tables) with imba,
where cells should be update based on other cells.

How can I generate this with Imba ?

Thanks

Are you talking about computed cells like in excel? I would probably use a library for the actual recomputation of values etc if the computations are expensive. If you could explain the usecase in greater detail it will be easier to create an example or help you in the right direction :slight_smile:

An example would be great as @somebee requested. Do you have a JavaScript example or even a screenshot of some other app would be useful?

Thanks.

To explain what I mean, I attached below my current imba solution.

There are three columns which are editable (Seed,Target,Version). If one click into
the field its getting orange which means it is editable. Mouse wheel events will increase or decrease
the value.

The Seed column has a special purpose. If the alt-key is pressed while receiving mouse wheel events,
a second value (width) is changed and additionally rows are inserted.

Up this point everything works in my solution.

However, if I release the alt-key the first value is changed in the Seed column and my expectation would be that the Seed value of the added rows are changed also. This indented behaviour is included in the <C> render method.

It seems to me, that I don’t understand how the render method is compiled into javascript.
Can you please enlight me on this :smiley:

Here my code:

tag edit_field < td
	prop row
	prop column
	prop low default: 0
	prop high default: 65536 - 1
	prop fast_increment default: 10
	
	def build
		@is_editing = false

	def setup
		@value = data[row][column]

	def value
		@value

	def do_update(e)
		if @is_editing
			update(e)		
			data[row][column] = value		
			
	def update(e)
		if e.native:deltaY > 0
			if e.native:shiftKey
				if @value + fast_increment <= high
					@value += fast_increment
			else
				@value++
				@value = high if @value > high
		else
			if e.native:shiftKey
				if @value - fast_increment >= low
					@value -= fast_increment
			else
				@value--
				@value = low if @value < low

	def render
		<self css:background-color=(@is_editing ? 'orange' : 'white') :click=(do @is_editing=true) :wheel.do_update :mouseleave=(do @is_editing=false)> value

tag seed < edit_field

	def build
		super
		@width = 1

	def value
		var s = "{@value}"
		s += ",{@width}" if @width>1
		s

	def update(e)
		if e.native:altKey
			if e.native:deltaY > 0
				if @width < 10
					@width++
			else
				if @width > 0
					@width--
		else
			super

tag version < edit_field

tag target < edit_field
	def build
		super
		@targets = {
			'ELA': '#ffd700' 
			'MAP': '#eec900'
			'FIT': '#ffa500'
			'STA': '#ee9a00'
			'ASM': '#cd8500'
			'PBD': '#cd8500'
		}

	def setup
		low = 0
		high = Object.keys(@targets):length - 1
		@value = Object.keys(@targets).indexOf(data[row][column])

	def value
		Object.keys(@targets)[@value]

tag B < tr
	prop config
	prop row



	def render
		<self>
			<td css:width=config:columns_width:step> (data[row]:seed.split(',')[1] == undefined ? data[row]:step : '')
			(data[row]:seed.split(',')[1] == undefined ? <target[data] row=row column='target' css:width=config:columns_width:target> : <td css:width=config:columns_width:target>)
			<td css:width=config:columns_width:time> (data[row]:seed.split(',')[1] == undefined ? data[row]:time : '')
			<seed[data] row=row column='seed' css:width=config:columns_width:seed>
			<td css:width=config:columns_width:name> data[row]:name
			(data[row]:seed.split(',')[1] == undefined ? <version[data] row=row column='version' css:width=config:columns_width:version> : <td css:width=config:columns_width:version>)
			<td> (data[row]:seed.split(',')[1] == undefined ? data[row]:message : '')


tag C < table
	prop config
	prop row

	def has_group
		log "seed={data[row]:seed}"
		data[row]:seed.split(',')[1] != undefined

	def render
		<self>
			<tbody>
				<B[data] config=config row=row>
				for j in [0...parseInt(data[row]:seed.split(',')[1])] when has_group
					data[row]:group[j] = {
						step: 'N/A'
						target: 'STA'
						time: '00:00:00'
						seed: "{parseInt(data[row]:seed.split(',')[0]) + j}"
						name: data[row]:name
						version: 0
						message: ''
					}
					<B[data[row]:group] config=config row=j>



tag D < table			
	def build
		@config = {
			columns_width: {
				step: 65
				target: 70
				time: 80
				seed: 60
				name: 250
				version: 70
			}
		}
		data = []
		
	def add_row
		data.push {
			step: 'N/A'
			target: 'STA'
			time: '00:00:00'
			seed: '0'
			name: ''
			version: 0
			message: 'Hello'
			group: []
		}

	def setup
		for i in [1..3]
			add_row		

	def render
		<self>
			<thead>
				<tr>
					<th css:width=@config:columns_width:step> 'Step'
					<th css:width=@config:columns_width:target> 'Target'
					<th css:width=@config:columns_width:time> 'Time'
					<th css:width=@config:columns_width:seed> 'Seed'
					<th css:width=@config:columns_width:name> 'Name'
					<th css:width=@config:columns_width:version> 'Version'
					<th> 'Message'
			<tbody>
				for row,i in data
					row:name = "n_{i}"
					<tr>
						<td colspan="7">
							<C[data] config=@config row=i>
			
Imba.mount <D>

Thanks for the example. I’m trying to wrap my head around it - hope to give some feedback tomorrow or wednesday :slight_smile: