Sample code for uibuilder

I am interested in the flexibility of uibuilder but understand at the same time that there's a significant learning curve for a non-hardcore developer like myself. However when I have some sample code I can usually work my way through.

So I wanted to get this POC working using this sample code (https://codepen.io/co0kie/pen/BEMVjd - no frameworks used) and proceed from there. Note: I have successfully installed and verified uibuilder with a few examples as per the nodered node guide.

Here's what I have done:

  1. Copied the following html code to index.html in the uibuilder node
<div class="dashboard">
  <header>
    <div class="f fe">
      <div class="icon icon-w"></div>
      <div class="heading">
        <h5 class="date">1 Feb 2019</h5>
        <h2 class="title">CCloudy</h2>
      </div>
    </div>
    
    <div class="weather f">
      <div>
        <strong>26°<sup>C</sup></strong>
        <p>Indoor Temp.</p>
      </div>
      <div>
        <strong>48.2%</strong>
        <p>Outdoor Humidity</p>
      </div>
      <div>
        <strong>52.99</strong>
        <p>Indoor Temp.</p>
      </div>
    </div>
  </header>
  <section>
  <!-- Category -->
    <div class="category">
      <ul>
        <li><a href="#!" class="active">Living Room</a></li>
        <li><a href="#!">Kitchen</a></li>
        <li><a href="#!">Dinning</a></li>
        <li><a href="#!">Weather</a></li>
      </ul>
    </div>
  <!-- Appliances -->
    <div class="appliances">
      
      <div class="appliance">
        <input type="checkbox" name="a" id="a">
        <label for="a">
          <i class="l"></i>
          <strong>Lamp</strong>
          <span data-o="opened" data-c="closed"></span>
          <small></small>
        </label>
      </div>
      
      <div class="appliance">
        <input type="checkbox" name="a" id="b">
        <label for="b">
          <i class="r"></i>
          <strong>Router</strong>
          <span data-o="opened" data-c="closed"></span>
          <small></small>
        </label>
      </div>
      
      <div class="appliance">
        <input type="checkbox" name="a" id="c">
        <label for="c">
          <i class="a"></i>
          <strong>Air</strong>
          <span data-o="opened" data-c="closed"></span>
          <small></small>
        </label>
      </div>
      
      <div class="appliance">
        <input type="checkbox" name="a" id="d">
        <label for="d">
          <i class="f"></i>
          <strong>Fridge</strong>
          <span data-o="opened" data-c="closed"></span>
          <small></small>
        </label>
      </div>
      
      <div class="m-player">
        <h2>Shared Devices</h2>
        <div class="player">
          <div class="disc"></div>
          <div class="artist">
            <p>Rosetta Stoned</p>
            <small>Tool</small>
          </div>
          <div class="controls">
            <input type="checkbox" name="a" id="p">
            <label for="p">
              <div class="control"></div>
            </label>
          </div>
        </div>
      </div>
      
    </div>
  </section>
</div>

<a href="https://www.youtube.com/watch?v=URUPsrmtYfs" target="_blank" title="Watch me speed code this" style="position: fixed; bottom: 10px; right: 10px"><img src="http://co0kie.github.io/codepen/youtube.png" alt=""></a>
  1. Copied the following css code to index.css in the uibuilder node
* {
  font-family: 'Lato', sans-serif;
}

body {
  height: 90vh;
  display: flex;
  background: aliceblue;
}

a {
  text-decoration: none;
  color: inherit;
}

ul {
  list-style: none;
}

.f {
  display: flex;
}

.fe {
  align-items: flex-end;
}

body {
  background-color: rgba(89, 162, 251, 0.61);
}

.dashboard {
  background-color: #f6f8fa;
  width: 420px;
  border-radius: 0 0 20px -15px black;
  margin: auto;
}

header {
  background-color: white;
  overflow: hidden;
  border-radius: 0 0 50px 50px;
  padding: 40px 40px 20px;
  box-shadow: 0 -5px 27px 0 rgba(128, 128, 128, 0.15);
}

.weather {
  margin-top: 40px;
  width: 100%;
  position: relative;
  overflow: hidden;
}
.weather sup {
  font-size: 11px;
  position: relative;
  top: -11px;
}
.weather::before {
  content: '';
  position: absolute;
  width: 130px;
  height: 60px;
  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 50%, white 100%);
  right: 0;
  bottom: 14px;
}
.weather > div {
  white-space: nowrap;
}
.weather > div + div {
  margin-left: 30px;
}
.weather > div > strong {
  font-size: 20px;
}
.weather > div > p {
  color: #9e9e9e;
  margin-top: 10px;
}

.category {
  overflow: hidden;
  margin-top: 30px;
}
.category ul {
  display: flex;
}
.category li + li {
  margin-left: 40px;
}
.category a {
  font-size: 17px;
  font-weight: 600;
  color: #858d9f;
  white-space: nowrap;
}
.category a:hover, .category a.active {
  color: #444;
}
.category a.active {
  position: relative;
}
.category a.active::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 6px;
  background-color: #444;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  bottom: -15px;
}

.appliances {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  width: 340px;
  margin: 30px auto;
}

.appliance {
  position: relative;
  height: 170px;
  width: 45%;
  margin: 10px 0;
}
.appliance span {
  position: relative;
}
.appliance span::before, .appliance span::after {
  text-transform: uppercase;
  font-size: 12px;
  position: absolute;
  left: 0;
}
.appliance span::before {
  content: attr(data-o);
  opacity: 0;
}
.appliance span::after {
  content: attr(data-c);
}
.appliance strong {
  margin: 70px 0 10px;
  display: block;
  font-size: 18px;
}
.appliance label {
  position: absolute;
  width: 74%;
  height: 71%;
  cursor: pointer;
  padding: 20px;
  box-shadow: 1px 0 10px 10px rgba(0, 0, 0, 0.03);
  border-radius: 30px;
}
.appliance label::before {
  border-radius: 30px;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  background-color: white;
  content: '';
}
.appliance label * {
  position: relative;
  transition: 200ms;
}
.appliance label small {
  position: absolute;
  width: 10px;
  height: 10px;
  background-color: #ff574e;
  border-radius: 10px;
  top: 30px;
  right: 20px;
  transition: 200ms;
}
.appliance label small::after, .appliance label small::before {
  content: '';
}
.appliance label .f {
  width: 16px;
  height: 22px;
  background-color: #3976f6;
  display: block;
  position: absolute;
  border-radius: 2px;
  top: 30px;
  background-image: linear-gradient(0deg, white 2px, transparent 2px), linear-gradient(0deg, white 12px, transparent 0);
  background-size: 17px 9px, 2px 15px;
  background-position: 0 0, 3px 0;
  background-repeat: no-repeat;
}
.appliance label .a {
  width: 23px;
  height: 10px;
  background-color: #3976f6;
  display: block;
  position: absolute;
  border-radius: 2px;
  top: 30px;
  background-image: linear-gradient(0deg, white 2px, transparent 2px);
  background-size: 17px 9px;
  background-position: 3px -2px;
  background-repeat: no-repeat;
}
.appliance label .a::after, .appliance label .a::before {
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  border-width: 3px;
  border-style: solid;
  border-color: transparent transparent #3976f6;
  top: 10px;
  border-radius: 50%;
  transform: rotate(72deg);
  display: block;
}
.appliance label .a::after {
  left: 14px;
}
.appliance label .a::before {
  left: 6px;
}
.appliance label .r {
  width: 23px;
  height: 9px;
  background-color: #3976f6;
  display: block;
  position: absolute;
  border-radius: 3px;
  top: 30px;
}
.appliance label .r::after, .appliance label .r::before {
  content: '';
  border-width: 2px;
  border-style: solid;
  border-color: rgba(57, 118, 246, 0.61) transparent transparent;
  border-radius: 50%;
  position: absolute;
  display: block;
}
.appliance label .r::after {
  width: 22px;
  height: 20px;
  top: -11px;
  left: -2px;
}
.appliance label .r::before {
  width: 16px;
  height: 20px;
  top: -6px;
  left: 1px;
}
.appliance label .l {
  width: 22px;
  height: 13px;
  background-color: #3976f6;
  display: block;
  position: absolute;
  border-radius: 22px 22px 0 0;
  top: 30px;
}
.appliance label .l::before {
  content: '';
  width: 3px;
  height: 8px;
  background-color: rgba(57, 118, 246, 0.61);
  display: block;
  top: -8px;
  position: absolute;
  border-radius: 3px;
  left: 9px;
}
.appliance label .l::after {
  content: '';
  position: absolute;
  width: 10px;
  height: 4px;
  background: rgba(57, 118, 246, 0.61);
  border-radius: 0 0 9px 9px;
  top: 14px;
  left: 6px;
}
.appliance input {
  display: none;
}
.appliance input:checked + label::before {
  content: '';
  background: linear-gradient(to bottom, #59a2fb 0%, #3976f6 100%);
}
.appliance input:checked + label * {
  color: white;
}
.appliance input:checked + label i {
  background-color: white;
}
.appliance input:checked + label i::before, .appliance input:checked + label i::after {
  background-color: rgba(255, 255, 255, 0.61);
}
.appliance input:checked + label i.f {
  background-image: linear-gradient(0deg, rgba(89, 162, 251, 0.61) 2px, transparent 2px), linear-gradient(0deg, rgba(89, 162, 251, 0.61) 12px, transparent 0);
}
.appliance input:checked + label i.a {
  background-image: linear-gradient(0deg, rgba(89, 162, 251, 0.61) 2px, transparent 2px);
}
.appliance input:checked + label i.a::before, .appliance input:checked + label i.a::after {
  background-color: rgba(255, 255, 255, 0);
  border-color: transparent transparent rgba(255, 255, 255, 0.61);
}
.appliance input:checked + label i.r {
  background-color: white;
}
.appliance input:checked + label i.r::before, .appliance input:checked + label i.r::after {
  background-color: rgba(255, 255, 255, 0);
  border-color: rgba(255, 255, 255, 0.61) transparent transparent;
}
.appliance input:checked + label small {
  width: 30px;
  height: 15px;
  background-color: #3976f6;
}
.appliance input:checked + label small::before {
  width: 13px;
  height: 13px;
  background-color: white;
  display: block;
  border-radius: 13px;
  top: 1px;
  position: absolute;
}
.appliance input:checked + label span::before {
  opacity: 1;
}
.appliance input:checked + label span::after {
  opacity: 0;
}

.heading .title {
  margin: 0;
  font-size: 36px;
}

.heading .date {
  margin: 10px 0;
  font-size: 16px;
}

.icon-w {
  position: relative;
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background-color: #feb103;
  margin-right: 30px;
  top: -7px;
}
.icon-w::after, .icon-w::before {
  content: '';
  position: absolute;
}
.icon-w::after {
  width: 28px;
  height: 13px;
  border-radius: 20px;
  background-color: #feb103;
  bottom: 0;
  left: 3px;
}
.icon-w::before {
  width: 20px;
  height: 20px;
  box-shadow: 10px -3px 0 -2px rgba(254, 177, 3, 0.59), 3px -15px 1px -7px rgba(254, 177, 3, 0.4), 11px -17px 1px -7px rgba(254, 177, 3, 0.4), 19px -13px 1px -7px rgba(254, 177, 3, 0.4), 22px -4px 1px -7px rgba(254, 177, 3, 0.4);
  border-radius: 50%;
}

.m-player {
  position: relative;
  width: 100%;
}
.m-player > h2 {
  margin-bottom: 5px;
  margin-top: 10px;
}
.m-player .player {
  border-radius: 10px;
  padding: 15px;
  background-image: linear-gradient(to right, #59a2fb 0%, #3976f6 100%);
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: white;
  box-shadow: 0 10px 10px 0 rgba(0, 0, 0, 0.24);
}
.m-player .artist {
  margin-right: auto;
  margin-left: 15px;
}
.m-player .artist p {
  margin: 0;
  font-weight: 600;
}
.m-player .disc {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-image: linear-gradient(50deg, rgba(255, 255, 255, 0) 45%, rgba(255, 255, 255, 0.15) 31%, rgba(255, 255, 255, 0) 72%), linear-gradient(-50deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0) 60%), repeating-radial-gradient(circle, #444 0, #444 2px, gray 2px, #545454 3px);
  position: relative;
}
.m-player .disc::before, .m-player .disc::after {
  content: '';
  position: absolute;
  margin: auto;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  border-radius: 50%;
}
.m-player .disc::before {
  width: 20px;
  height: 20px;
  background: black;
  border: 2px solid #5d5d5d;
}
.m-player .disc::after {
  width: 8px;
  height: 8px;
  background: white;
}
.m-player .control {
  width: 52px;
  height: 10px;
  background-image: linear-gradient(to right, rgba(255, 255, 255, 0.61) 2px, transparent 2px), linear-gradient(to right, rgba(255, 255, 255, 0.61) 2px, transparent 2px), linear-gradient(to right, white 4px, transparent 0), linear-gradient(to right, white 4px, transparent 0);
  background-position: 0 0, 47px 0, 20px 0, 26px 0;
  background-size: 2px 12px, 2px 12px, 4px 12px, 4px 12px;
  background-repeat: no-repeat;
  position: relative;
  cursor: pointer;
  transition: 200ms;
}
.m-player .control::after, .m-player .control::before {
  content: '';
  position: absolute;
  border-width: 6px;
  border-style: solid;
  top: -1px;
}
.m-player .control::before {
  left: -2px;
  border-color: transparent rgba(255, 255, 255, 0.61) transparent transparent;
}
.m-player .control::after {
  right: 1px;
  border-color: transparent transparent transparent rgba(255, 255, 255, 0.61);
}
.m-player .controls input {
  display: none;
}
.m-player .controls input:checked + label .control {
  background-size: 2px 12px, 2px 12px, 0 0, 0 0;
  background-position: 6px 0, 40px 0, 20px 0, 26px 0;
}
.m-player .controls input:checked + label .control::after {
  right: 18px;
}
.m-player .controls input:checked + label .control::before {
  left: -2px;
  border-width: 0;
}
  1. Nothing in index.js

  2. The output should look like this
    Dashboard

  3. What I see is very different. Appears it doesn't take any CSS into account if I understand this correctly

  4. When I inspect the page all I get is a warning

I do apologize if I'm asking the obvious but hope you can point me to the right direction

You have a non-valid html file and you have a styles.css file. Where is the reference to the styles ?
You have to tell the browser how to render the html.

See example.

The jquery errors are strange but not related, because your files don't reference jquery.

1 Like

The codepen works as expected for me.

You haven't made any reference to any of the required uibuilder files so you will not have any interactivity as yet.

In order to use uibuilder in your front-end code, you need to add the reference to the uibuilderfe.js library at the very least and then you will need a script that calls uibuilder.start(). Note that uibuilderfe.js is self-loading in the browser so it only needs a script reference to it.

1 Like

Got it working now. Thanks for pointing that out. Looking back it's obvious. Hopefully with this change I have left the starting blocks of html and css :slight_smile:

Wanted to get this off the list first. With this basic code now working I will try to bring in some data from Node-RED. Exciting times ahead.

1 Like