Skip to main content
Error Showing Content - please login as admin for details.
Error Showing Content - please login as admin for details.

Customize Edit UI/UX

Tutorial Home

2sxc UI - Toolbar Workflows

Toolbars will automatically do things like open a dialog or refresh the page when the dialog closes. But sometimes you want to override or change the default behavior - like:

  1. Prevent refresh on dialog close - to retrieve the data in JS
  2. Prevent creating new if a specific condition applies

This is what the Workflows are for. You can register custom before and after code to run, change specs or prevent the action from executing. Read the workflow docs or the toolbar docs to learn more about this.

Important: Usually only editors see these toolbars - so saving won't work. Hover over the various boxes to see the result - like this:

Important: The feature "Public Use of Edit Form" is disabled

The feature is needed for anonymous users to use the Edit Form. Register your site here https://patrons.2sxc.org/ to get access to the feature.

New syntax: Standard TagToolbar

Float over this box to get a (+) button. When you click it and close the dialog again, the page will not refresh.
Instead, you'll see console messages that a custom JS took over the process.

  @{
    var standartToolbar = Kit.Toolbar.Empty().New("UiEmptyHelloWorld").Settings(hover: "left", show: "always");
  }
  <div class="alert alert-primary" style="width: 50%;">
    <div id='tagWithToolbar2' @standartToolbar>
      Float over this box to get a (+) button. 
      When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
      Instead, you'll see console messages that a custom JS took over the process.
    </div>
  </div>
  

Old syntax: Standard TagToolbar

Float over this box to get a (+) button. When you click it and close the dialog again, the page will not refresh.
Instead, you'll see console messages that a custom JS took over the process.

  <div class="alert alert-primary" style="width: 50%;">
    <div id='tagWithToolbar1' @Edit.TagToolbar(toolbar: new [] 
      { "toolbar=empty", "+new?contentType=UiEmptyHelloWorld" }, settings: new { hover = "left", show = "always" } 
    )>
      Float over this box to get a (+) button. 
      When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
      Instead, you'll see console messages that a custom JS took over the process.
    </div>
  </div>
  

New syntax: Standard Inline Toolbar

    When you click it and close the dialog again, the page will not refresh.
    Instead, you'll see console messages that a custom JS took over the process.

      <div class="alert alert-primary" style="width: 50%;">
        <div id='inlineToolbar2'>
          @Kit.Toolbar.Empty().New("UiEmptyHelloWorld").AsTag()
          When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
          Instead, you'll see console messages that a custom JS took over the process.
        </div>
      </div>
      

    Old syntax: Standard Inline Toolbar

      When you click it and close the dialog again, the page will not refresh.
      Instead, you'll see console messages that a custom JS took over the process.

        <div class="alert alert-primary" style="width: 50%;">
          <div id='inlineToolbar'>
            @Edit.Toolbar(toolbar: new [] { "toolbar=empty", "+new?contentType=UiEmptyHelloWorld" })
            When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
            Instead, you'll see console messages that a custom JS took over the process.
          </div>
        </div>
        

      More Stuff

      You can do much more - like change icons, call call-parameters etc. Read the how-to and the specs for this.

      Source Code of this file

      Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

      @inherits Custom.Hybrid.Razor14
      <!-- unimportant stuff, hidden -->
      <div class="alert alert-success">
        <h2>New syntax: Standard TagToolbar</h2>
        
        @{
          var standartToolbar = Kit.Toolbar.Empty().New("UiEmptyHelloWorld").Settings(hover: "left", show: "always");
        }
        <div class="alert alert-primary" style="width: 50%;">
          <div id='tagWithToolbar2' @standartToolbar>
            Float over this box to get a (+) button. 
            When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
            Instead, you'll see console messages that a custom JS took over the process.
          </div>
        </div>
        
        
      </div>
      <div class="alert alert-secondary">
        <h2>Old syntax: Standard TagToolbar</h2>
        
        <div class="alert alert-primary" style="width: 50%;">
          <div id='tagWithToolbar1' @Edit.TagToolbar(toolbar: new [] 
            { "toolbar=empty", "+new?contentType=UiEmptyHelloWorld" }, settings: new { hover = "left", show = "always" } 
          )>
            Float over this box to get a (+) button. 
            When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
            Instead, you'll see console messages that a custom JS took over the process.
          </div>
        </div>
        
        
      </div>
      <div class="alert alert-success">
        <h2>New syntax: Standard Inline Toolbar</h2>
        
        <div class="alert alert-primary" style="width: 50%;">
          <div id='inlineToolbar2'>
            @Kit.Toolbar.Empty().New("UiEmptyHelloWorld").AsTag()
            When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
            Instead, you'll see console messages that a custom JS took over the process.
          </div>
        </div>
        
        
      </div>
      <div class="alert alert-secondary">
        <h2>Old syntax: Standard Inline Toolbar</h2>
        
        <div class="alert alert-primary" style="width: 50%;">
          <div id='inlineToolbar'>
            @Edit.Toolbar(toolbar: new [] { "toolbar=empty", "+new?contentType=UiEmptyHelloWorld" })
            When you click it and close the dialog again, the page will <em>not refresh</em>. <br>
            Instead, you'll see console messages that a custom JS took over the process.
          </div>
        </div>
        
        
      </div>
      
      <script>
        // This workflow definition will run on every action, just to log what's happening
        const workflowToLog = {
          command: 'all',   // Run on every command/action
          phase: 'all',     // Run before and after
          code: (wfArgs) => {
            console.log("Toolbar asked to to something - here are the details.", wfArgs);
          }
        }
      
        // This is the workflow definition we will register to stop page refresh
        const workflowToDisableRefresh = {
          command: 'refresh',   // The command name it's for
          phase: 'before',      // The workflow-step should run before the command is executed
          code: (wfArgs) => {   // The code which should be run
            console.log('Toolbar asked to refresh, will return false to stop it. These are the arguments we got.', wfArgs);
            return false;       // Return false to stop this command from happening
          }
        };
      
        // Attach event-listener to the TagToolbar parent, so we can register the workflow when the toolbar is created
        var parent = document.getElementById('tagWithToolbar1');
        parent.addEventListener('toolbar-init', (initEvent) => {
          console.log("Workflow Demo: Tag Toolbar was initialized - event kicked in - will now register");
          const workflow = initEvent.detail.workflow;
      
          workflow.add(workflowToLog);
          workflow.add(workflowToDisableRefresh);
      
          // Stop the event here, otherwise parent elements which have an event listener would get triggered as well
          initEvent.stopPropagation();
        });
      
        // Attach event-listener to the TagToolbar parent, so we can register the workflow when the toolbar is created
        var parent = document.getElementById('tagWithToolbar2');
        parent.addEventListener('toolbar-init', (initEvent) => {
          console.log("Workflow Demo: Tag Toolbar was initialized - event kicked in - will now register");
          const workflow = initEvent.detail.workflow;
      
          workflow.add(workflowToLog);
          workflow.add(workflowToDisableRefresh);
      
          // Stop the event here, otherwise parent elements which have an event listener would get triggered as well
          initEvent.stopPropagation();
        });
      
        // Attach event-listener to the parent of the inline-toolbar, so we can register the workflow when the toolbar is created
        var parent = document.getElementById('inlineToolbar');
        parent.addEventListener('toolbar-init', (initEvent) => {
          console.log("Workflow Demo: Inline Toolbar was initialized - event kicked in - will now register");
          const workflow = initEvent.detail.workflow;
      
          workflow.add(workflowToLog);
          workflow.add(workflowToDisableRefresh);
      
          // Stop the event here, otherwise parent elements which have an event listener would get triggered as well
          initEvent.stopPropagation();
        }); 
        var parent = document.getElementById('inlineToolbar2');
        parent.addEventListener('toolbar-init', (initEvent) => {
          console.log("Workflow Demo: Inline Toolbar was initialized - event kicked in - will now register");
          const workflow = initEvent.detail.workflow;
      
          workflow.add(workflowToLog);
          workflow.add(workflowToDisableRefresh);
      
          // Stop the event here, otherwise parent elements which have an event listener would get triggered as well
          initEvent.stopPropagation();
        }); 
      </script>
      
      <!-- unimportant stuff, hidden -->
      <!-- unimportant stuff, hidden -->