Repeat content using template

When you begin to build dynamic content, you need to repeat some patterns like a series of comments, a list of contents, a dropdown list etc...

HTML5 introduce a special Element called "template" to allow define the pattern to reproduce for each elements you want.

I will not cover the use of slots (not all browser is compatible) but you can use it in the same way described here

Example of a dropdown element using a array of strings

var domtemplate = `<div class="dropdown" id="dropdowntest">
  <div class="dropdown-trigger">
    <button class="button" aria-haspopup="true" aria-controls="dropdown-menu2" id="dropdownbutton">
      <span>Click me</span>
	  <span class="icon is-small">
	  <i class="fas fa-angle-down" aria-hidden="true"></i>
	  </span>
    </button>
  </div>
  <div class="dropdown-menu" id="dropdown-menu2" role="menu">
    <div class="dropdown-content">
	  <template id="mytemplatedropdown">
	  <a href="#"  class="dropdown-item" id="itemtpl">
		  <span>Hello </span><span id="itemtext"></span>
      </a>
	  </template>
	  <div id="dropdownitemscontent"></div>
    </div>
  </div>
</div>`

var arraydynamiccontent []string = []string{"World", "Me", "Cat"}

func main() {
	hogosuru.Init()

	// we get the current document
	if doc, err := document.New(); hogosuru.AssertErr(err) {

		//we got the head
		if head, err := doc.Head(); hogosuru.AssertErr(err) {

			if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {

				link.SetRel("stylesheet")
				link.SetHref("https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css")
				head.AppendChild(link.Node)

			}

			if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {

				link.SetRel("stylesheet")
				link.SetHref("https://bulma.io/vendor/fontawesome-free-5.15.2-web/css/all.min.css")
				head.AppendChild(link.Node)

			}

		}

		if body, err := doc.Body(); hogosuru.AssertErr(err) {
			//we insert the html code
			body.InsertAdjacentHTML("beforeend", domtemplate)

			if dropdowntest, err := GetDivBySelector(body.Element, "#dropdowntest"); hogosuru.AssertErr(err) {
				if dropdownbutton, err := GetButtonBySelector(body.Element, "#dropdownbutton"); hogosuru.AssertErr(err) {
					dropdownbutton.OnClick(func(e event.Event) {
						//when click we open or close the drop down
						if list, err := dropdowntest.ClassList(); hogosuru.AssertErr(err) {
							list.Toggle("is-active")
						}

					})
				}

			}

			if contentitems, err := GetDivBySelector(body.Element, "#dropdownitemscontent"); hogosuru.AssertErr(err) {
				contentitems.SetTextContent("")
				if t, err := GetTemplateBySelector(body.Element, "#mytemplatedropdown"); hogosuru.AssertErr(err) {
					//now we want the content of the template to duplicate it
					if fragment, err := t.Content(); hogosuru.AssertErr(err) {
						if cloneNode, err := fragment.GetElementById("itemtpl"); hogosuru.AssertErr(err) {

							//we loop for each content
							for _, name := range arraydynamiccontent {
								if clone, err := doc.ImportNode(cloneNode.Node, true); hogosuru.AssertErr(err) {
									if a, ok := clone.(htmlanchorelement.HtmlAnchorElement); ok {

										//we search the span txtContent to modify value

										if spantxt, err := GetSpanBySelector(a.Element, "#itemtext"); hogosuru.AssertErr(err) {
											spantxt.SetTextContent(name)
										}

										contentitems.Append(a.Element)

									}
								}
							}

						}

					}
				}

			}

			//we search element like contents to loop the data and template

		}

	}

	ch := make(chan struct{})
	<-ch

}

Let's take a closer look at the code

First we get the head of the document, we create an htmllink with the ref to the bulma css and fontawesome and attach it to the head

		if head, err := doc.Head(); hogosuru.AssertErr(err) {

			if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {

				link.SetRel("stylesheet")
				link.SetHref("https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css")
				head.AppendChild(link.Node)

			}
			
			if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {

				link.SetRel("stylesheet")
				link.SetHref("https://bulma.io/vendor/fontawesome-free-5.15.2-web/css/all.min.css")
				head.AppendChild(link.Node)

			}

		}

We load the drop down contents at the end of the body

body.InsertAdjacentHTML("beforeend", domtemplate)

We search the #dropdowntest element and we toggle their class "is-active" when click on #dropdownbutton element

if dropdowntest, err := GetDivBySelector(body.Element, "#dropdowntest"); hogosuru.AssertErr(err) {
	if dropdownbutton, err := GetButtonBySelector(body.Element, "#dropdownbutton"); hogosuru.AssertErr(err) {
		dropdownbutton.OnClick(func(e event.Event) {
			//when click we open or close the drop down
			if list, err := dropdowntest.ClassList(); hogosuru.AssertErr(err) {
				list.Toggle("is-active")
			}

		})
	}
}

We search the template element and the #itemtpl element. For each data in arraydynamiccontent ({"World", "Me", "Cat") we clone a copy of #itemtpl, set the content of #itemtext and append this item inside the div #dropdownitemscontent

if contentitems, err := GetDivBySelector(body.Element, "#dropdownitemscontent"); hogosuru.AssertErr(err) {
	contentitems.SetTextContent("")
	if t, err := GetTemplateBySelector(body.Element, "#mytemplatedropdown"); hogosuru.AssertErr(err) {
		//now we want the content of the template to duplicate it
		if fragment, err := t.Content(); hogosuru.AssertErr(err) {
			if cloneNode, err := fragment.GetElementById("itemtpl"); hogosuru.AssertErr(err) {

				//we loop for each content
				for _, name := range arraydynamiccontent {
					if clone, err := doc.ImportNode(cloneNode.Node, true); hogosuru.AssertErr(err) {
						if a, ok := clone.(htmlanchorelement.HtmlAnchorElement); ok {

							//we search the span txtContent to modify value

							if spantxt, err := GetSpanBySelector(a.Element, "#itemtext"); hogosuru.AssertErr(err) {
								spantxt.SetTextContent(name)
							}

							contentitems.Append(a.Element)

						}
					}
				}

			}

		}
	}
}

The final HTML content of #dropdownitemscontent will be

<div id="dropdownitemscontent"><a href="#" class="dropdown-item" id="itemtpl">
		  <span>Hello </span><span id="itemtext">World</span>
      </a><a href="#" class="dropdown-item" id="itemtpl">
		  <span>Hello </span><span id="itemtext">Me</span>
      </a><a href="#" class="dropdown-item" id="itemtpl">
		  <span>Hello </span><span id="itemtext">Cat</span>
      </a>
</div>

And the dropdown will work as expected:

Last updated