0

I created a custom component in AEM using the multifield functionality. However, it automatically places the values in a long string with commas in between.

I have gotten the values in an array using a custom JS file, but still can't figure out how to separate them or list them out.

I'm not sure if I can accomplish this inside the loop in my JS file or in the HTL file that is referencing the JS by using data-sly-repeat or data-sly-list

I would like each value to be a separate link tag with the value from the input as the href.

here's the js file:

"use strict";

use(function() {

  var csspath = properties["csspath"];

  var links = "";

  for(var i = 0; i < csspath.length; i++) { 

      links += csspath[i]
  }

  return {
      linkarray: links
  };

});

and the html that references it:

<sly data-sly-use.csslinks="csslinks.js" />

${csslinks.linkarray}

right now the html prints out simply

test1test2

but I want it to appear as

<link href="test1.css" />
<link href="test2.css" />

without the user having to actually input <link href=.... />

I have tried adding html syntax in the JS file like so...

for(var i = 0; i < csspath.length; i++) { 
    links += '<link href="' + csspath[i] + '.css" />'
}

and even just

for(var i = 0; i < csspath.length; i++) { 
     links += csspath[i] + "<br />"
 }

but it gives errors every time

toniedzwiedz
  • 17,895
  • 9
  • 86
  • 131
Holly Michelle
  • 95
  • 2
  • 15

1 Answers1

1

I generally shun the WCM Use API in favour of Sling Models and I don't have an AEM instance at hand while writing this but here's some general tips you may find helpful.

In the WCM Use code that you posted:

"use strict";

use(function() {

  var csspath = properties["csspath"];

  var links = "";

  for(var i = 0; i < csspath.length; i++) { 

      links += csspath[i]
  }

  return {
      linkarray: links
  };

});

you're building a string based on an array obtained from the page properties binding. Since you're aiming to build HTML elements anyway, this is an unnecessary step.

Instead, return the array and iterate over it in your HTL script. HTL is where you should be building your presentation layer.

"use strict";

use(function() {

  var cssPaths = properties["csspath"];

  return {
      linkArray: cssPaths
  };

});

Then, in your HTL script, iterate over the array, rendering HTML.

<link data-sly-use.csslinks="csslinks.js"
      data-sly-repeat.link="${csslinks.linkArray}" href="${link}" />

Check out the documentation on data-sly-repeat.

To make it even more simple, you could use the out-of-the-box properties binding and skip the WCM Use altogether. The type is not explicitly named anywhere in your JS or HTL code but properties saved in the content repository as string arrays (String[]) can be handled by HTL itself. If you're using granite/ui/components/foundation/form/multifield in the dialog, this should be sufficient:

<link data-sly-repeat.link="${properties['csspath']}" href="${link}" rel="stylesheet" />

Now, that explains how to achieve what you're trying to do in HTL... However, outputting CSS links this way seems like a dubious idea in the first place.

Including CSS files generally isn't such a manual process on an AEM project. What you should do instead is organize your CSS into clientlibs, declare the dependencies in the component that renders the page and have AEM provide you with the right CSS and JS code.

toniedzwiedz
  • 17,895
  • 9
  • 86
  • 131
  • you are a lifesaver! these solutions worked perfectly. I read the documentation, but I just started working with AEM and crxde a few days ago, so it's still foreign to me. This works as a loop. however, it adds them side-by-side. Is there any easy way to make them onto separate lines, as in a list? this is just a component that im working on in my local for now. my site will have multiple sites and templates within it, so we think this is the best way to add specific css files in one template that we may not need in another – Holly Michelle Oct 30 '17 at 16:19
  • @HollyMichelle what kind of a list? Do you mean to load the CSS or simply render a list of links to CSS files so someone can view them? Can you provide an example of the desired markup? – toniedzwiedz Oct 30 '17 at 16:24
  • `` tags should not be placed in the body of the document anyway. If you want to inlcude the CSS, render those in the head section and use Clientlibs as opposed to a manually coded component. If you actually want to display the content, it still doesn't matter if a new line character is there between the tags or not. HTML doesn't care about whitespace. Visually placing elements on separate lines should be done using CSS. – toniedzwiedz Oct 30 '17 at 16:37
  • toniedzwiedz I got it to display how i wanted with data-sly-list. I'm creating this component with the HTL in a "customheaderlibs.html" to allow the author to input css files in the page's properties tabs that will be placed in the header (not just rendered there, but actually functional) and then create another component with the exact same functionality to put js files in the footer with that HTL in a customfooterlibs file. but i will look into clientlibs for sure. Thanks for your help – Holly Michelle Oct 30 '17 at 17:08