Display wizard without refresh


#1

I'm working on a plugin and would like to display a wizard box when the print finishes. I have this kind of working, but the wizard window only shows when I refresh the page. Sometimes even shift-reload is required. Is there any way to force it?


#2

I think we need more details about your existing solution to help (github-link or inline sourcecode).
From my perspective my solution would look like this:

  1. event-listener for print finished
  2. send printDone-message to frontend
  3. frontend shows wizard

pseudo-code

init.py
1)
def on_event(self, event, payload):
 if event == Events.PRINT_DONE:
2)
   self._plugin_manager.send_plugin_message(self._identifier,
                                            dict(showWizard=True))
<yourplugin>.js
3)
// handle data from server        
self.onDataUpdaterPluginMessage = function(plugin, data) {
  if (plugin != PLUGIN_ID) {
    return;
  }
  if (data.showWizard==true) {
  // e.g. do jquery-stuff for opening the wizard

#3

ahh..there is an existing WizardPlugin (http://docs.octoprint.org/en/master/plugins/mixins.html#wizardplugin).
I didn't know that.

I looked into the source-code and I think the wizard is only called on Browser-Reload (you already mentioned) and also it stores the information if the wizard was already shown to the user:

views.py
	wizard_required = implementation.is_wizard_required()
	wizard_ignored = octoprint.plugin.WizardPlugin.is_wizard_ignored(seen_wizards, implementation)

After evaluating this vars the main-view is build by iterating over all includes templates.
image
In the screenshot you can see that the wizard-list is empty -> no wizard is shown!

My conclusion: It looks like it is not possible to show the wizard "on demand" (like print finished). Maybe with some "JavaScript-Hack".

Maybe someone has more expirence with the WizardPlugin-Mixin.

BR
Olli


#4

Yes this is my problem. I am iterating the counter that tracks if the wizard has been seen so it shows after each print completes. The print gets done, but no wizard until I refresh the page, and sometimes i even have to shift-refresh. So I need some window to pop up that tells the user to refresh the page, but he'll have to refresh the page to see that one.......
If I could force the "reload now" window I suppose it would be acceptable, since the printer is presumably idle. I'm not too good with the normal javascript, let alone hacking it.
If I restart OctoPrint it remembers the wizard is needed from the print completed in the previous session, but that's REALLY hacky.
I also researched overlaying text on mjpeg-streamer, but it's not possible. If I could switch to UV4L streamer I can overlay text, but I haven't been able to figure that out yet either.


#5

Why do you want to reuse the Wizard-Plugin? Just rebuild the dialog by your own. So, you have full control of the behaviour.
If you want to create a modal-dialog, you can do it with my first approach.

More details from my Plugin "DeleteAfterPrint":
plugin_sidebar.jinja2

	<!-- Modal-Dialog -->
	<div id="sidebar_deleteFilesDialog" class="modal hide fade">
		<div class="modal-header">
			<a href="#" class="close" data-dismiss="modal" aria-hidden="true">&times;</a>
			<h3 class="modal-title">Delete all listed files?</h3>
		</div>
		<div class="modal-body">
			<div >
				<div id="noEffectedFiles" style="display:none" data-bind="if: effectedFiles.length == 0"><i>No effected files!</i></div>
				<ul id="effectedFilesList" style="display:none" data-bind="foreach: effectedFiles">
					<li>(<!--ko text: $data.destination--><!--/ko-->)&nbsp;&nbsp;<!--ko text: $data.filename--><!--/ko-->
					</li>
				</ul>
			</div>
		</div>
		<div class="modal-footer">
			<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
			<button class="btn btn-danger btn-confirm" ><i class="fa fa-spinner fa-spin" data-bind="enabled:!requestInProgress(), css: {disabled: requestInProgress()}, visible: requestInProgress()"></i> Delete now </button>
		</div>
	</div>

And some JavaScript to initialize and to show the dialog:

plugin.js

function showFilesForDeletionDialog(){
		// show dialog
		var editDialog = $("#sidebar_deleteFilesDialog");
		var confirmButton = $("button.btn-confirm", editDialog);
		confirmButton.unbind("click");
		confirmButton.bind("click", function() {
			alert ("DELETE NOW");
			self.requestInProgress(true);
			$.ajax({
				url: API_BASEURL + "plugin/"+PLUGIN_ID,
				type: "POST",
				dataType: "json",
				data: JSON.stringify({
					command: "deleteConfirmed",
				}),
				contentType: "application/json; charset=UTF-8"
			}).done(function(data){
				//alert("back from server");
				editDialog.modal("hide");
			}).always(function(){
				self.requestInProgress(false);
			}) ;
		});
		editDialog.modal({
			//minHeight: function() { return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); }
		}).css({
			width: 'auto',
			'margin-left': function() { return -($(this).width() /2); }
		});
}

#6

I'll try that. The wizard says "system setup" at the top which I have no idea how to change, and I was almost resolved to using the hacky restart Octoprint way to get the wizard to show himself.
Thanks for pointing me in the right direction!


#7

The included wizard stuff is for system setup related stuff - e.g. fetching input from the user on updates or plugin installs that is needed for operation.

It is not a generic wizard for other tasks. If you want that, I fear you'll really need to build it yourself.


#8

I abandoned the wizard. But in case anyone is interested I found the answer to my original question - to force a reload of the web interface that shows updated fields. I'm sure there's probably a better way, but running tcpkill for about 6 seconds is enough to close client connections and the server realizes stuff has changed and presents the "please reload" dialog. If nothing change you really have to watch your browser to even notice. Kind of "hacky", but I haven't observed any detrimental effects (for my purposes the printer is idle anyway).