Button click in servlet (with soy template) does not call javascript

I am doing a settings page for my plugin. The page is initialized with a servlet, rendered with a soy template. I alos have some javacript code, but that code does not seem to trigger.

 Servlet code

pageBuilderService.assembler().resources().requireContext("com.Company.RdvRequestValidator.settings");
response.setContentType("text/html;charset=UTF-8");
soyTemplateRenderer.render(response.getWriter(), "com.Company.RdvRequestValidator:displaySettings-soy", "com.Company.RdvRequestValidator.displaySettings", data);

 

settings.soy

{namespace com.Company.RdvRequestValidator}
 
/**
 * @param repository
 * @param validatorSettings
 */
{template .displaySettings}
<!DOCTYPE html>
<html>
  <head>
    <meta name="decorator" content="stash.repository.settings">
    <meta name="projectKey" content="{$repository.project.key}">
    <meta name="repositorySlug" content="{$repository.slug}">
    <meta name="activeTab" content="rdv-valid-settings-page">
    <title>Pull Request Validator settings for {$repository.project.name}/{$repository.name}</title>
  </head>
  
  <body>
    <h2>Pull Request Validator</h2>
    <br>
     <label for="skipMergeCommits">
	    <select id="skipMergeCommits">
	        {for $i in range(7)}
		        {call .optionLine}
	                {param optionValue: $i /}
	                {param skipValue: $validatorSettings.mergeCommitsSkip /}
	            {/call}
	        {/for}
	    </select>
	    &nbsp merge commits ignored for out of date check.
	</label>
	<div class="buttons-container">
		<div class="buttons">
		<br>
 			<input class="aui-button aui-button-primary settings-save" type="submit" id="submit_valid_set" name="submit_valid_set" value="Save" accesskey="s">
		</div>
 	</div>
   </body>
</html>
{/template}

 

atlassian.xml

<servlet key="pull-valid-settings" class="com.Company.stash.merge.checks.ValidatorSettingsServlet">
        <url-pattern>/pull-valid-settings/*</url-pattern>
    </servlet>
     
    <stash-resource key="displaySettings-soy">
        <directory location="/soy/">
            <include>/**/settings.soy</include>
        </directory>
        <dependency>com.atlassian.stash.stash-web-plugin:global</dependency>
        <dependency>com.atlassian.stash.stash-web-plugin:server-soy-templates</dependency>
    </stash-resource>
    
    <stash-resource key="settings-resources">
        <directory location="/js/">
            <include>/**/settings.js</include>
        </directory>
        <context>com.Company.RdvRequestValidator.settings</context>
        <dependency>com.atlassian.stash.stash-web-plugin:global</dependency>
    </stash-resource>
    
    <web-item key="rdv-valid-settings-page" weight="30" section="stash.repository.settings.panel/repository-settings-addons-section">
        <!-- Only for non-personal repositories -->
        <condition class="com.atlassian.stash.web.conditions.IsPersonalRepositoryCondition" invert="true"/>
        <label>Pull Request Validator</label>
        <tooltip>Configures the repository Pull Request validator</tooltip>
         <link linkId="pull-valid-settings-button">${navBuilder.pluginServlets().path('pull-valid-settings', $project.key, $repository.slug).buildRelNoContext()}</link>
    </web-item>

 

 

settings.js

require([ 'jquery', 'underscore', 'util/ajax', 'model/page-state' ], 
    function($, _, ajax, pageState) { 
      var save = function(payload) { 
       return ajax.rest({ 
          url : AJS.contextPath() + '/rest/pull-valid-settings/latest/projects/' + pageState.getProject().get('key') + '/repos/' + pageState.getRepository().get('slug') + '/pull-valid-settings', 
          type: 'PUT', data: payload  }); 
     }; 
 
$(document).on('click', '.settings-save', function(e) { 
     e.preventDefault(); 
     window.alert("sometext"); 
     var payload = _.reduce($('.settings-save').toArray(), function(memo, el) { 
        var box = document.getElementById('skipMergeCommits'); 
        memo['mergeCommitsSkip'] = box.options[box.selectedIndex].value; 
        return memo; }, {}); 
     save(payload); }); 
 
});

 

I placed an alert in the click function, but it does not get in there. I tried several things, like changing 'input.aui-button' by the other class name the button has, but nothing. I don't have any error in the console when executing it. It just does nothing when clicking the button.

 

8 answers

Hi. Well, I see no class="content-body" in your soy?

Yes, I know. I tried that because I tried fixing it with an example online. I was using "settings-save" originally. I edited my code.

0 votes

There must be something else at play here, because I just tried the minimal set of code needed to reproduce your example (same button markup, same servlet code and Soy) and it worked fine. Is there anything in the Stash log when you install your plugin that might indicate it's failing to load? Anything in the console when the page loads, as opposed to when you click the button?

No error at loading plugin or page. Failing to load the plugin would mean that the page would not display, no? I think the issue is related to the js file not being loaded or not being linked to the soy template. I realized the namespace in the servlet and the one in the soy template are completly different. The issue might be caused by an error in manipulating namespaces or the ressource context value.

0 votes

The namespaces aren't too important in this case, obviously if you're seeing the template the Soy resources and rendering part is working fine. Requesting the resources for a context should cause them to be loaded - I assume you've double checked that the context value is the same both in the Plugin XML and in the requireContext call already? The other thing you can check in Chrome Dev Tools (that's what I know best, other browsers should have similar features) is that the script is actually being loaded. You should be able to press Cmd-P (ctrl-P on Windows I think?) in Dev Tools and get a fuzzy file picker dialog - type "settings.js" and see if it shows up and loads. If it is there, try setting a breakpoint inside the top level function and refreshing the page - the breakpoint should persist. That way you can check if the code is actually running, and make sure the event handler is being attached correctly. Like I said, I don't see anything obviously wrong - so it's probably something simple we've both missed! :)

The context value is the same both in the Plugin XML and in the requireContext call. I'm able to open the settings.js file with the chrome debug tool as you said. I placed a breakpoint in the click function, but nothing happens. I modified the event definition to $('.settings-save').on('click', function (e) , it did not change anything.

0 votes

Very strange! There must be something external to the snippets of code you've provided that's causing the issue. I created a new empty plugin and brought across the bare minimum code required to reproduce your issue, and it still seems to be working for me. I changed a few names here and there, but I don't think I changed anything materially. I've put the plugin code up on Bitbucket so you can compare and maybe it will help to find what isn't working for you? https://bitbucket.org/mszczepanski/button-test-plugin/src You'll need to provide query params for a project key and repo slug: http://localhost:7990/stash/plugins/servlet/pull-valid-settings/?project=PROJECT&repoSlug=my-repo Will be interested to see what you find.

I know now why you could not see the issue, in was in a part of the atlassian-plugin.xml that I did not post... I was missing the <component-import key="pageBuilderService" interface="com.atlassian.webresource.api.assembler.PageBuilderService" /> I delete my target folder between each run of atlas-debug, but it never gave me an error saying that this was missing... It's working now. Well, I still have an error in the save function, maybe related to the rest call, but at least the script is now loaded :) Thank you for your support.

Was able to fix my rest call issue too :)

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Thursday in Agile

How Scrum works? It starts with training and education

To answer “How scrum works,” most of the teams I've worked with first addressed the question: “where to start?”  That question applies to both implementation and improvements on the Scrum framew...

202 views 3 6
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you