Numeric Inputs

Description:  Must be placed on equip.  This component can toggle back and forth between the two views by checking the checkbox at the top.  The first view has plus and minus buttons to control the setpoint.  The second view has a textbox where the user can type in the desired value.

ModelnumericInputs.zip


Code

Template

<div class="s-horizontal s-middle s-msb">
    <input class ="s-msb s-msl" type="checkbox" id="switch" checked='{{checked}}'/>
  &nbsp;Enable Numeric Inputs
</div>
<div class="s-horizontal s-wrap s-flex view-container s-container">
    <div class="s-horizontal s-wrap s-flex s-container">
{{#points}}
<div class="s-horizontal view-superman-value status-stale s-box s-msr s-msb s-flex">
    <div class="s-vertical s-bottom s-fWd s-fHt">
        <div class="s-fWd s-fHt s-horizontal s-middle s-center view-superman-value s-name s-hand" on-click="magicB">{{.navName}}</div>
        <div class="s-fWd s-msb"></div>
      {{#if checked}} 
      <div class="s-horizontal s-fWd bottom-box">
          <div class="s-horizontal s-middle s-center s-fWd">
          <input type="text" placeholder="{{.enteredVal}} {{.unit}}" value="{{.newVal}}" class="s-text s-msr" /></div>
          <div class="s-right">
                <button class="view-default s-buttonSubmit" on-click="updateValue">Submit</button>
          </div>
        </div>
      {{else}}
      <div class="s-horizontal s-fWd bottom-box">
                <button class="view-default s-button" on-click="decrement">-</button>
                &nbsp;
                <button class="view-default s-button" on-click="increment">+</button>
           <div class="s-horizontal s-middle s-center s-fWd s-hand" on-click="magicPoint">{{.enteredVal}} {{.unit}}</div>
        </div>
      {{/if}}
    </div>
</div>
{{/points}}</div>
</div>


Model

{
    data:{
        inputs:false,
        points:null,
        pollId: null
    }
}


Style

.s-button{
    width:35px;
    font-size:14px;
}
.s-buttonSubmit{
    width:70px;
    font-size:14px;
}
.s-box{
    height:70px;
    min-width: 180px;
}
.bottom-box{
    height:80px;
}
.s-name{
    height:5px;
}
.s-container{
    min-width: 200px;
}
.s-text{
    width:100%;
    height:100%;
}
.check{
    height: 0;
    width: 0;
    visibility: hidden;
}
.s-label {
    cursor: pointer;
    text-indent: -9999px;
    width: 40px;
    height: 20px;
    background: grey;
    display: block;
    border-radius: 100px;
    position: relative;
}
.s-label:after {
    content: '';
    position: absolute;
    top: 5px;
    left: 5px;
    width: 10px;
    height: 10px;
    background: #fff;
    border-radius: 10px;
    transition: 0.3s;
}
input:checked + .s-label {
    background: #bada55;
}
input:checked + .s-label:after {
    left: calc(100% - 5px);
    transform: translateX(-100%);
}
.s-label:active:after {
    width: 10px;
}
.s-hand{
    cursor: pointer;
}
.s-fHt{
    height: 100%;
}
.s-fWd{
    width: 100%;
}
.s-horizontal{
    display: flex;
    flex-direction: row;
}
.s-middle{
    align-items: center;
}
.s-vertical{
    display: flex;
    flex-direction: column;
}
.s-right{
    justify-content: flex-end;
}
.s-center{
    justify-content: center;
}
.s-bottom{
    justify-content: flex-end;
}
.s-wrap{
    flex-wrap: wrap;
}
.s-flex{
    flex: 1 1 auto;
}
.s-msr{
    margin-right: 5px;
}
.s-msb{
    margin-bottom: 5px;
}
.s-msl{
    margin-left: 5px;
}
.s-canScroll{
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}


Init

this.ractive.fire("obtainData");
var self = this.ractive;
var val;
var showVal;

self.observe('points', function(nVal) {
    if (nVal && nVal.length) {
        var ids         = nVal.map(function(p) {return p.id});
        var idToIndex   = [];
        nVal.forEach(function(p, idx) {
            idToIndex[p.id] = idx;
        });
        
        self.set({idToIndex:idToIndex});
        
        var previousPollId  = self.get('pollId');
        if (previousPollId)
            finstack.unbind(previousPollId);
            
        var bindId = finstack.bindMultipleToMethod(ids, 'curVal', function(nVal, point) {
            point       = point.toObj();
            var index   = self.get('idToIndex')[point.id];
            
            if (index != -1)
                self.set('points.' +index+ '.enteredVal', nVal);
        });
        
        self.set('pollId', bindId);
    }
});

this.ractive.on("increment", function(event){
    var point   = this.get(event.keypath);
    val     = parseFloat(point.curVal);
    showVal = val;
    console.log("ShowVal", showVal);
    showVal    += 1;
    console.log("New ShowVal", showVal);
    var promise = finstack.eval('invoke('+point.id+', "Set Default", {self:'+point.id+',val:'+showVal+'})');
     promise.then(function(item)
     {
         var newVal         = showVal;
         var newKeypath     = event.keypath + ".curVal";
         self.set(newKeypath,newVal);
         console.log(newVal);
     }.bind(this));
});
 
this.ractive.on("decrement", function(event) {
    var point   = this.get(event.keypath);
    val     = parseFloat(point.curVal);
    showVal = val;
    showVal    -= 1;

     var promise = finstack.eval('invoke('+point.id+', "Set Default", {self:'+point.id+',val:'+showVal+'})');
     promise.then(function(item)
     {
         var newVal         = showVal;
         var newKeypath     = event.keypath + ".curVal";
         self.set(newKeypath,newVal);
         console.log(newVal);
     }.bind(this));
});

this.ractive.on("updateValue", function(event){
     var point     = this.get(event.keypath);
    // console.log("point", point);
    //  var myObject  = self.get(event.keypath);
    //  console.log("myObject",myObject);
    //  var myObject2 = this.get(event.keypath);
    //  var point2    = this.get('points');
     val       = parseFloat(point.newVal);
    //  console.log("val",val);
    //  console.log("point2", point2);
    //  console.log("myObject2", myObject2);
     var promise   = finstack.eval('invoke('+point.id+', "Set Default", {self:'+point.id+',val:'+val+ '})');
     promise.then(function(item) {
         var newVal         = item.result.toObj(false,false,true);
         var newKeypath     = event.keypath + ".curVal";
         console.log("Updated with " +newVal);
        //  console.log(newKeypath);
         self.set(newKeypath,newVal);
        //  console.log(newVal);
     }, function(err) {
         console.log("Error updating value", err);
     });
});


this.ractive.on("magicB", function(event) {
    var item    = this.get(event.keypath);
    if (item)
    top.app.ShowRelatedBubbles(item.id, item.id, false, event);
});

this.ractive.on("magicPoint", function(event) {
    var item    = this.get(event.keypath);
    if (item)
    top.app.ShowRelatedBubbles(item.id, item.id, true, event);
});


Program

To add a new program go to the programs menu on the left menu

  • Click the + at the bottom to add a new program
  • Under Program Name, name your program
  • Under Program Target Filter, type stackRactive
  • Next click the three dots in the top right corner
  • Click the gear that appears as you hover over this
  • Turn on Invokes the Function
  • Change the dropdown to Custom Event
  • Type obatinData and click the gray save button
  • Copy and paste the code below into the main section
  • Save and your done!

var myTarget = query('targetPoint');
var sPoint = this;
finstack.eval('readAll(equipRef=='+myTarget.pointId+' and sp)', function(data){
    var myPoints    = data.result.toObj();
    myPoints.forEach(function(item){
       item.enteredVal = GetPrettyValue(item);
    });
    sPoint.points   = myPoints;
});