Hiev Grid Display

Greetings to everyone in the forum.

I am trying to add on top of Hiev Inventory System a CSS grid layout display, which in my opinion could be more suited than a table to display a character sheet with data like hit points, strength value, etc…

The idea is during UpdateDisplay() to create a set of div starting from a parent div with some data- attributes that are then used to build the CSS layout.

I would like to hear from the users of these framework, which probably have better experience than me in this kind of activity, if it is something that could be generally useful and for which there could be a need, and reviewing the code if there is something done wrongly (or that can be done better!) as well as suggestions, ideas, etc…

Mainly to Hiev: would it make sense to you (and are you willing) to embed this code (or a future better tuned implementation) inside the inventory system? I would prefer to contribute to an existing (and widely used) framework rather then reinventing the wheel…
One major doubt that I have for the current implementation is related to the data-templateX, which control and format a content string, if it should:

  1. Be taken out from a property of the item/bag which should allow less typing but in my opinion move the presentation layer inside the data layer. I would probably like that the same information could be displayed in different ways inside the story.
  2. Placed inside the div, with the cons to have to write a little bit more data tag. This is the reason why you can see below that I have created a Macro that use an input object to create the div. I would prefer to write an array of objects rather than the div itself.

Here is the code:

//START UPDATEDISPLAY JS CODE
if ($(Matches[i]).data("uinv") === "table") {  /* Update tables */
	[...]
}
/* Add update code for future display objects here. */
else if ($(Matches[i]).data("uinv") === "grid") {  // Update div : NEW CODE!!!
	Table = $(Matches[i]);
	BagName = Table.attr("id");
	Table.find("[data-uinv='item']").off();  // Release handlers
	if(UInv.BagExists(BagName)){
		Table.empty();
		Item = Table.data("item"+Count);
		while(Item!=undefined){
			var Property = Table.data("property"+Count);
			if(!Array.isArray(Property))Property=[Property];
			
			var Header = Table.data("header"+Count);
			var Footer = Table.data("footer"+Count);
			var AreaName = Item.length>0?Item:Property[0];
			Txt = Table.data("template"+Count);

			if(Item!="" && UInv.ItemHasPocket(BagName,Item)>0){
				var AllBags = Object.keys(UInv.GetItemPropertyValue(BagName,Item,"UInvPocket"));
				var AllItems = [];
				AllBags.forEach(function(item,index,array){AllItems.push(UInv.GetItemsArray(item));});
			}else{
				var AllBags = [BagName];
				var AllItems = [[Item]];
			}
			
			var Div = $('<div></div>')
				.attr('data-uinv','grid-item')
				.attr('data-bagname',BagName)
				.addClass('grid-item-'+Count)
				.css('grid-area',AreaName)
			;
			
			$.each(AllBags,function(j,bag){
				$.each(AllItems[j],function(k,key){
					var value = new Array(Property.length);
					$.each(Property,function(z,val){
						if(key==""){ //Item '' means to get a property of the bag itself
							value[z] = UInv.GetBagPropertyValue(bag,Property[z]);
						}else{
							value[z] = UInv.GetItemPropertyValue(bag,key,Property[z]);
						}
					});
					(Txt===undefined)?Div.append(value):Div.append(eval("`"+Txt+"`"));
				})
		});						
			if(Header!=undefined){Div.prepend(Header);}
			if(Footer!=undefined){Div.append(Footer);}
			Div.appendTo(Table);
			Count++;
			Item = Table.data("item"+Count);
		}
	}
}
//START MACRO CODE GRID
(function () {
  "use strict";
  Macro.add(['grid'], {
    tags: null,
    handler: function handler() {
      try {
        var content = this.payload[0].contents.trim();
        if (content) {
          	var $el = $('<div></div>')
          		.attr('data-uinv','grid')
          		.attr('id',this.args[0])
          		.addClass('grid-charsheet-container')
          	;
          $.each(JSON.parse(content),function(i,obj){
			$el
          		.attr('data-item'+i,obj.item)
          		.attr('data-property'+i,function(k,val){return (Array.isArray(obj.property)?JSON.stringify(obj.property):obj.property);})
          		.attr('data-template'+i,obj.template)
          	;
          	if(obj.hasOwnProperty('header')){
          		$el.attr('data-header'+i,obj.header)
          	}
          	if(obj.hasOwnProperty('footer')){
          		$el.attr('data-footer'+i,obj.footer)
          	}
          });
          $el.appendTo(this.output);
        }
      } catch (ex) {
        return this.error("bad evaluation: " + (_typeof(ex) === 'object' ? ex.message : ex));
      }
    }
  });
})();
//START EXAMPLE
//Widget example
<<grid "player1">>[
	{"item":"","property":"name","template":"<b>NAME</b>: ${value[0]}"},
	{"item":"hitpoints","property":["initial","current"],"template":"<b>HITPOINTS</b>: ${value[0]}<br>${value[1]}"},
]<</grid>>
//This should produce the following div:
<div id="player1" data-item0="" data-property0="name" data-template0="<b>NAME</b>: ${value[0]}" data-item1="hitpoints" data-property1="["initial","current"]" data-template1="<b>HITPOINTS</b>: ${value[0]}<br>${value[1]}"/>

//UInv bag
case "bern":
	var val1 = dice('3d6');
	BagProperties = {
		,name: "I am player one"
	},

	BagItems = [
		 {"hitpoints": {initial: val1, current: val1}}
	];
	break;
//CSS
.grid-charsheet-container{
	grid-template-areas:
		'name name'
		'hitpoints hitpoints'
	;		
}

Honestly, while the other portions of the Universal Inventory System (UInv) code are nearly complete, the current “Display” portion of UInv is still in its infancy (mainly because it had to be done last). The current UInv “Table” is an early example of how the UInv display elements will work.

Once I get back to work on it, the next update (v0.9.8; no ETA, sorry) is planned to have 1) a “Clothing Mannequin” display element, for equipping items, clothes, swapping outfits, etc., 2) a dropdown list display element which allows images and more complex data display, and 3) a color swapping tool so you don’t have to create a bunch of separate sprites which are all basically identical, except for some of the colors. (The latter two of which are currently mostly complete.)

The v1.0.0 version of UInv will include a way to combine all of the display elements together. It will let you build complex objects on screen from the various UInv display elements, which would automatically fill themselves in with UInv data.

Anyways, if you want to link to an example of what you’re looking for in the future, I’ll be happy to take a look at it and incorporate anything useful into the final design.

Thanks! :grinning:

Hi HiEv

Thanks for the reply. I have managed to create the demo and upload it here:

https://ifelseif.neocities.org/demo.html

I hope it gives the feeling of what I am looking for.
Any feedback and suggestion are of course wellcome and very well appreciated!!

Yeah, the ability to make something like that, using something like the current “Table Builder” options, will definitely be included in the v1.0 version of UInv.