0 votes
by (240 points)

In this moment I try create full inventory API for my game.

I create CSS Grid layout then add from array current avalibale items (type of all items - object ) with image and link to use item.

Next I need add dialog who will be opened by click on image.

Dialog contets full item image and item lore.

All I do this from JS code without using JQuery.

I tryed add click event by official Dialog API by adding him in "div" and "a" elements and this not success.

I don't add my macros code beacose his little crazy and big. If my code yet need I can add him in next message.
Sorry for my english.

 

2 Answers

0 votes
by (68.6k points)

Please show the relevant parts of your code—i.e., those dealing with the attempts to use the Dialog API.

by (240 points)
			var img = 'pics/' + item.folder + item.image ;
			txt += '<div class="col-' + rw + '">';
			
			txt += '<a id="' + item.id + '"> @@.itemImg;[img[' + img + ']]@@ </a>';
			if(item.uses > 0) {
				txt += '<<link "Uses x' + item.uses + '">>';
			} else {
				txt += '<<link "Count x' + item.count + '">>';
			}
			txt += '<<useFromInv $' + item.id + '>>';
			txt += '<<goto ' + passage() + '>> <</link>>';
			txt += '</div>';
			id = '#' + item.id;
			dg += '[img[' + img + ']]\n';
			dg += item.lor;
		});
	}
	txt += '</div>';
	new Wikifier(this.output, txt); 
	if (dg != '') {
		Dialog.addClickHandler(id, null, function (dg) {
		Dialog.setup("Item observe");
		Dialog.wiki(dg);
		});
	}

 

by (159k points)

If I understand your Macro handler code correctly the target of your Dialog.addClickHandler() function call is the anchor element you just dynamically added to the contents of the this.output buffer.

As I understand things the contents of the this.output buffer isn't added to the page's DOM until after all of the Passage contents has been process, which means the anchor element doesn't exist in the page's DOM at the time you are calling the Dialog.addClickHandler() function.

by (44.7k points)

If what greyelf says is happening is correct, then instead of adding the click handler later on, you could just add an "onclick" event handler directly to the <a> element, and have the event trigger a function which sets up and opens the dialog.

(I'm suggesting this while half-asleep, so I may have overlooked something, but I think that should work.)

by (240 points)
Then need wait answer from TheMadExile, about how is better release this functional. To be precise, when and how to use Dialog API in this situation.
by (159k points)

You will need to delay the calling of the Dialog.addClickHandler() function until after the new content has been rendered, and one method you can use to do this is the :passagedisplay event.

note: you didn't include the whole of your macro's handler code, nor an example of how you call that macro, so I had to make some assumptions on what both of these things might look like.

Macro.add('doit', {
	handler: function () {

		/* Some assumptions. */
		const item = this.args[0];
		const rw = 'rw-class';
		var txt = '<div>';
		var id = '';
		var dg = '';

		/* Original code example. */
		var img = 'pics/' + item.folder + item.image;
		txt += '<div class="col-' + rw + '">';
			
		txt += '<a id="' + item.id + '"> @@.itemImg;[img[' + img + ']]@@ </a>';

		if(item.uses > 0) {
			txt += '<<link "Uses x' + item.uses + '">>';
		} else {
			txt += '<<link "Count x' + item.count + '">>';
		}
		txt += '<<useFromInv $' + item.id + '>>';
		txt += '<<goto ' + passage() + '>> <</link>>';
		txt += '</div>';

		id = '#' + item.id;

		dg += '[img[' + img + ']]\n';
		dg += item.lor;

		txt += '</div>';

		new Wikifier(this.output, txt);

		if (dg != '') {
			/* Delay the setup of the click handler. */
			$(document).one(':passagedisplay', function (ev) {
				Dialog.addClickHandler(id, null, function () {
					Dialog.setup("Item observe");
					Dialog.wiki(dg);
				});
			});
		}
	}
});
<<set $item to {
	id: 'an-item',
	folder: 'folder/',
	image: 'image.png',
	uses: 0,
	count: 1,
	lor: 'some lore'
}>>

<<doit $item>>

The first of the above examples used the jQuery <element>.one() function to monitor for the :passagedisplay event, and then sets up the reqired Dialog Click Handler.

warning: You may have some issues if you are calling this within a loop, or if the loop has many iterations.

0 votes
by (240 points)

Okey, a full code with removed 1 logic bug and you event catch variant:

Macro.add("gridInv", {
	handler : function () {
		var txt = '<div class="inv-pl">';
		var dg = [];
		var id = [];
		if (State.variables.inventory.length === 0) {
			txt = 'Inventory is empty.';
		} else {
			var nm = 1;				
			for (var i = 0; i < State.variables.inventory.length; i++) { 
				var item = State.variables.inventory[i];
				var rw = '';
				switch (nm) {
				case 1:
					rw = 'one';
					nm++;
				break;
				case 2:
					rw = 'two';
					nm++;
				break;
				case 3:
					rw = 'three';
					nm++;
				break;
				case 4:
					rw = 'four';
					nm = 1;
				break;
				}
				var img = 'pics/' + item.folder + item.image ;
				txt += '<div class="col-' + rw + '">';
				
				txt += '<a id="' + item.id + '"> @@.itemImg;[img[' + img + ']]@@ </a>';
				if(item.uses > 0) {
					txt += '<<link "Uses x' + item.uses + '">>';
				} else {
					txt += '<<link "Count x' + item.count + '">>';
				}
				txt += '<<useFromInv $' + item.id + '>>';
				txt += '<<goto ' + passage() + '>> <</link>>';
				txt += '</div>';
				id.push('#' + item.id);
				dg.push('[img[' + img + ']]\n' + item.lor);
			}
		}
		txt += '</div>';
		new Wikifier(this.output, txt); 
		if (dg != '') {
			$(document).one(':passagedisplay', function (ev) {
				for (var i = 0; i < id.length; i++) {
						Dialog.addClickHandler(id[i], null, function () {
						Dialog.setup("Observing ID: ");
						Dialog.wiki(dg[i]);
					});
				}
			});
		}
		
	}
});

Geted me this Screenshot.

And this is what I'm don't understand. Beacause dr and id is empty when i try added dialogs. Also State.variables unvisible for addClickHandlel in this construction.

Any idea?

...