I am building a Framework7 MVC app and found myself in a dead end alley. I have a form which I need to evaluate. This form contains selects. I am using localStorage to store the form values and everything works OK in that sense, I mean everything is stored correctly. ¿What is the issue? When I fill the form I answer some questions on textareas inputs, select inputs and inputs. everything goes fine until I try to reedit the form, then everything is display correctly on the form, including the score i got from my previous answers, but, the selects appears as if I have never touch them. Their previously selected value is stored but not display on the form. I have found that the issue is caused by the fact that I have set numerical values to the options values but what the form show is "yes" or "no". If I change the option values to "yes" or "no" then the form displays correctly but I need to set "5" or "0" because I need to evaluate the user's answers.
This is my code
The form
<li style="margin-top:-10px;">
<input style="visibility:hidden;height:1px;" value="0" name="choice" onchange="checkTotal()"/>
<input style="visibility:hidden;height:1px;" value="1" type="checkbox" name="choice" onchange="checkTotal()" checked="on">
</li>
<li><div class="item-content">1. ¿Sueles quejarte de sentirte mal?</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<select name="pr1" id="pr1" onchange="checkTotal()">
<option class="item-inner" value="5">No</option>
<option class="item-inner" value="0">Si</option>
</select>
</div>
</div>
</div>
<div class="item-content">En tal caso,</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<textarea class="resizable" id="pr1notes" placeholder="¿cuál es la causa?">{{model.pr1notes}}</textarea>
</div>
</div>
</div>
</li>
The functions on the editController
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
and the model
Protection.prototype.setValues = function(inputValues, extras) {
for (var i = 0, len = inputValues.length; i < len; i++) {
var item = inputValues[i];
if (item.type === 'checkbox') {
this[item.id] = item.checked;
}
else {
this[item.id] = item.value;
}
}
for (var i = 0, len = extras[0].length; i < len; i++) {
var item = extras[0][i];
if((item.id).localeCompare("pr1notes")==0) {this[item.id] = item.value;}
}
console.log('starting loop for extras 3...');
for (var i = 0, len = extras[2].length; i < len; i++) {
var item = extras[2][i];
this[item.name] = item.value;
}
};
Protection.prototype.validate = function() {
var result = true;
if (_.isEmpty(this.prdate)
) {result = false;}
return result;
};
Protection.prototype.getSelectFields = function() {
return ['pr1'];
}
What should I change in order to keep my "5" or "0" values on the select options while the form options still show "yes" or "no" to the user just like this: <select name="pr1" id="pr1" onchange="checkTotal()"><option class="item-inner" value="5">No</option><option class="item-inner" value="0">Si</option></select>?
need anything else to help you understand the issue?
The simplest solution
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].value).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
Just changed this line
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
and changed .label for .value.
Related
Am trying to save Cascading dropdown options to local storage, and am coming up with a few issues:
-The dropdowns are registered in Localstorage when changed, but they are not saving on refresh
-They are not being retrieved (probably because of the former issue).
Here's a link to the testing site:
https://www.flighteducation.co.uk/Panelcraft/Bespoke.php
Here is the script for the cascading dropdowns:
var subjectObject = {
"WALL": {
"NON FIRE RATED": ["BEADED", "NON-BEADED"],
"FIRE RATED 1 HOUR": ["BEADED", "NON-BEADED"],
"FIRE RATED 2 HOUR": ["BEADED", "NON-BEADED"],
},
"CEILING": {
"NON FIRE RATED": ["BEADED", "NON-BEADED"],
"FIRE RATED 1 HOUR": ["BEADED", "NON-BEADED"]
}
}
window.onload = function() {
var subjectSel = document.getElementById("subject");
var topicSel = document.getElementById("topic");
var chapterSel = document.getElementById("chapter");
for (var x in subjectObject) {
subjectSel.options[subjectSel.options.length] = new Option(x, x);
}
subjectSel.onchange = function() {
chapterSel.length = 1;
topicSel.length = 1;
for (var y in subjectObject[this.value]) {
topicSel.options[topicSel.options.length] = new Option(y, y);
}
}
topicSel.onchange = function() {
chapterSel.length = 1;
var z = subjectObject[subjectSel.value][this.value];
for (var i = 0; i < z.length; i++) {
chapterSel.options[chapterSel.options.length] = new Option(z[i], z[I]);
}
}
}
The code for local storage looks like this:
let options = [position, fire, frame];
for (let i = 0; i < options.length; i++) {
if (window.localStorage.getItem('dropdownValue') === options[i].value) {
options[i].setAttribute('selected', 'selected');
}
}
$(function () {
$('#number').change(function () {
localStorage.setItem('BespokeOrderInput', this.value);
});
if (localStorage.getItem('BespokeOrderInput')) {
$('#number').val(localStorage.getItem('BespokeOrderInput')).trigger('change');
}
});
$(function () {
$('#subject').change(function () {
localStorage.setItem('BespokeOrderForm1', this.value);
});
if (localStorage.getItem('BespokeOrderForm1')) {
$('#subject').val(localStorage.getItem('BespokeOrderForm1')).trigger('change');
}
});
with the $(function) being repeated for each item
the code looks like this for each dropdown (id being different for each)
<select class="list-dropdown" name="chapter" id="chapter">
<option id="frame" value="" selected="selected">PLEASE SELECT FIRE RATING FIRST</option>
</select>
The inputs for the numbers are saving and retrieving with no problem, but as mentioned above dropdowns are not working.
Very new to Localstorage stuff, and I appreciate anyone's time!
thanks
I have tried to extend the Dynamic-Forms app from angular 2 cookbook so I can have an array of multiple fields. I have been able to show the fields, but when I'm filling the form, I'm getting just the last element of the array filled.
Hier is my plunker with that state of the app:
//question-array.ts
import { QuestionBase } from './question-base';
export class ArrayQuestion extends QuestionBase<string> {
controlType = 'array';
options:{childe:FormElement<string>}[] = [];
constructor(options:{} = {}){
super(options);
this.options = options['options'] || [];
}
}
//question-control.service.ts
...
toFormGroup(formelements: QuestionBase<any>[] ) {
let group:any = {};
formelements.forEach(element => {
console.log("+element",element);
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = new FormControl(e.value || '');
});
arr.push(new FormGroup(locobj))
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
//dynamic-form-question.component.html
...
<div *ngSwitchCase="'array'" [formArrayName]="question.key">
<div *ngFor="let item of question.options; let i=index" [formGroupName]="i" >
<div *ngFor="let element of item.element">
<div *ngIf="element.controlType === 'textbox'" >
<label>{{element.label}}</label>
<input [formControlName]="element.key" [id]="element.key" [type]="element.type" />
</div>
<div *ngIf="element.controlType === 'dropdown'" >
<label>{{item.label}}</label>
<select [id]="element.key" [formControlName]="element.key">
<option *ngFor="let opt of element.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
</div>
</div>
</div>
...
http://plnkr.co/edit/DZ05fO
Best regard,
Shefki
I found the bug, the problem was that I was passing the same reference in the form group her is what i changed:
//question-control.service.ts
toFormGroup(formelements: QuestionBase[] ) {
let group:any = {};
formelements.forEach(element => {
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = e.value || '';
});
arr.push(new FormGroup(this.getFormControlObject(locobj)));
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
private getFormControlObject(keys){
let retobj = {};
Object.keys(keys).forEach(function(key) {
retobj[key] = new FormControl(keys[key]);
});
return retobj;
}
Hier is a working plunker
http://plnkr.co/edit/4IMKdLKE51n41jzYY8sU
I'm new to JavaScript and have written this code. It worked before, but now it just don't, and I don't understand why. The text on the button doesn't even change to "PAUSE". When I try it in the browser it says after a while that "localhost is not responding due to a long-running script."
<div>
<div id="tabataBox">
<p id="PauseGoText"></p>
<p id="stopwatch">CLICK TO START WORKOUT</p>
<button id="tabataButton" onclick="startPause()">START</button>
</div>
<span class="circle" id="el-1"></span>
<span class="circle" id="el-2"></span>
<span class="circle" id="el-2"></span>
<span class="circle" id="el-3"></span>
<span class="circle" id="el-4"></span>
<span class="circle" id="el-5"></span>
<span class="circle" id="el-6"></span>
<span class="circle" id="el-7"></span>
<span class="circle" id="el-8"></span>
</div>
</div>
var time = 0;
var running = 0;
var everySecond = true;
var max = 20;
var numberOfTimes = 1;
function startPause() {
if (running == 0) {
running = 1;
document.getElementById("tabataButton").innerHTML = "PAUSE";
increment();
}
else {
running = 0;
document.getElementById("tabataButton").innerHTML = "START";
}
}
function reset() {
time = 1;
document.getElementById("stopwatch").innerHTML = "0";
if (everySecond == true)
{
everySecond = false;
max = 20;
document.getElementById("tabataBox").style.backgroundColor = "green";
document.getElementById('el-'+numberOfTimes).style.backgroundColor = "green";
numberOfTimes++;
document.getElementById("PauseGoText").innerHTML = "REST";
}
else {
everySecond = true;
max = 10;
document.getElementById("tabataBox").style.backgroundColor = "red";
document.getElementById("PauseGoText").innerHTML = "GO!";
}
}
function increment() {
if (running == 1) {
setTimeout(function () {
time++;
if (time > max) {
reset();
}
document.getElementById("stopwatch").innerHTML = time;
increment();
}, 1000)
}
}
I have got list data from a SharePoint list and have binded one column of data into a dropdown using knockoutJS. I am now trying to remove duplicates from the binded results, but am struggling.
Here's my code so far:
var Info = ko.observable();
var AppModel = {
Acts: ko.observableArray([]),
sel: ko.observable()
}
$(function () {
$.ajax({
dataType: "json",
url: "MYLIST/_vti_bin/listdata.svc/LISTNAME?$select=Title",
data: {},
success: dataCallBack
});
ko.applyBindings();
});
function dataCallBack(data) {
var newData = [];
for(var idx=0; idx < data.d.results.length; idx++) {
function dataCallBack(data) {
var newData = [];
for(var idx=0; idx < data.d.results.length; idx++) {
var e = data.d.results[idx];
var foundItem = return ko.utils.arrayFirst(newData, function(item) {
return item == e;
});
if (!foundItem){
newData.push(e);
}
}
AppModel.Acts(newData);
}
HTML Here
<select id="location-input" data-bind="options: AppModel.Acts,
optionsText: 'Title
optionsCaption: 'Choose...',
value: AppModel.sel">
</select>
Can anyone advise as to where I'm going wrong? I think the for loop is breaking at the if statement.
Your attempt for checking duplicates is wrong.
Try something like this:
var foundItem = ko.utils.arrayFirst(newData, function(item) {
return item == e;
});
if (!foundItem)
{
newData.push(e);
}
I need to make a column where you can select grid rows with input:checkbox. Grids like ones used by Yahoo, Google etc have something like that.
I made something but I have some problems and I think that is not a good aproach also.
It's posible to have checkboxes in rows and click on them directly, not like in example4-model ?
My idea was :
< div id="inlineFilterPanel" class="slick-header-column" style="padding: 3px 0; color:black;">
<input type="checkbox" name="selectAll" id="selectAll" value="true" / >
< input type="text" id="txtSearch2" value="Desktops" />
</div>
d["check"] = '< INPUT type=checkbox value='true' name='selectedRows[]' id='sel_id_<?php echo $i; ?>' class='editor-checkbox' hideFocus />';
grid.onSelectedRowsChanged = function() {
selectedRowIds = [];
$('#myGrid' + ' :checkbox').attr('checked', '');
var rows = grid.getSelectedRows();
for (var i = 0, l = rows.length; i < l; i++) {
var item = dataView.rows[rows[i]];
if (item) {
selectedRowIds.push(item.id);
$('#sel_' + item.id).attr('checked', 'checked');
}
}
};
function selectAllRows(bool) {
var rows = [];
selectedRowIds = [];
for (var i = 0; i < dataView.rows.length; i++) {
rows.push(i);
if (bool) {
selectedRowIds.push(dataView.rows[i].id);
$('#sel_' + dataView.rows[i].id).attr('checked', 'checked');
} else {
rows = [];
$('#sel_' + dataView.rows[i].id).attr('checked', '');
}
}
grid.setSelectedRows(rows);
}
grid.onKeyDown = function(e) {
// select all rows on ctrl-a
if (e.which != 65 || !e.ctrlKey)
return false;
selectAllRows(true);
return true;
};
$("#selectAll").click(function(e) {
Slick.GlobalEditorLock.cancelCurrentEdit();
if ($('#selectAll').attr('checked'))
selectAllRows(true);
else
selectAllRows(false);
return true;
});
Thanks!
I've added a sample implementation of a checkbox select column to http://mleibman.github.com/SlickGrid/examples/example-checkbox-row-select.html
This is part of the upcoming 2.0 release.