How to create a key:value object from several HTML inputs - javascript

I got the following HTML:
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
The amount of slot_subclass may be unlimited.
I need to parse all these inputs and make an object where the key is the value of first input of slot_subclass (slot_name) and value is the value of the second (slot_type).
I tried the following:
$(".slot").map(function(){
return $(this).val();
}).get();
but I just get a plain array of values. I may use jQuery for this task. Thank you.
UPD_1 In order to handle for the same keys I chose the following code (if someone interested):
jsonObj = [];
$(".slot_subclass").each(function() {
var slot_name = $(this).find("input[name=slot_name]").val();
var slot_type = $(this).find("input[name=slot_type]").val();
item = {};
item[slot_name] = slot_type;
jsonObj.push(item);
});
console.log(jsonObj);
Thank you everyone for help.

Like this code:
100% working and tested
jsonObj = [];
$(".slot_subclass").each(function() {
var slot_name = $(this).("input[name=slot_name]").val();
var slot_type = $(this).("input[name=slot_type]").val();
item = {};
item["slot_name"] = slot_name;
item["slot_type"] = slot_type;
jsonObj.push(item);
});
console.log(jsonObj);
Example:
jsonObj = [];
$(".slot_subclass").each(function() {
var slot_name = $(this).find("input[name=slot_name]").val();
var slot_type = $(this).find("input[name=slot_type]").val();
item = {};
item["slot_name"] = slot_name;
item["slot_type"] = slot_type;
jsonObj.push(item);
});
console.log(jsonObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name" value="1">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type" value="11">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name" value="2">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type" value="22">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name" value="3">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type" value="33">
</div>
</div>

Firstly note that there's no such thing as a 'JSON object'. JSON is a notation for serialising data to a string. It's never an object.
With regard to your code, map() returns an array. In your example this array will contain values only. Instead you need to change that to return an object that holds the values of the input elements within each .slot_subclass group.
Once you've done that to build the array, you can use JSON.stringify to build your JSON string, something like this:
var arr = $('.slot_subclass').map(function() {
var obj = {};
$(this).find('.slot').each(function() {
obj[this.name] = this.value;
});
return obj;
}).get();
console.log(arr);
var json = JSON.stringify(arr);
console.log(json);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>

You should use each(), not map()
$('.test').on('click', function() {
var obj = {}
$(".slot_subclass").each(function() {
var $slots = $(this).find('.slot');
obj[$slots.eq(0).val()] = $slots.eq(1).val()
})
console.log(obj)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<button class="test">Test</button>

Following is based on :
where key is the value of first input
// set values for demo
setDemoValues()
// get data based on above values
var res = {};
$('.slot_subclass').each(function() {
var $inputs = $(this).find('.slot');
res[$inputs[0].value] = $inputs[1].value;
})
console.log(res)
function setDemoValues() {
$('.slot_subclass').each(function(i) {
$(this).find('.slot').val(function() {
return this.name + (i + 1);
})
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>
<div class="slot_subclass">
<div class="form-group">
<input type="text" class="form-control slot" name="slot_name">
</div>
<div class="form-group">
<input type="text" class="form-control slot" name="slot_type">
</div>
</div>

You're on a right way but you need to change you algorithm.
Let's see $(".slot_subclass") is array of div elements - iterate that array, and got both 'key' and 'value' values :). For each element of $(".slot_subclass") you can get access to first and second nested inputs by something like $(el).find('.slot') and first element of that array is a first input, second is a second input.

So, what you can do is query all of the inputs, set their name as the key and their value as their input.
The problem you can run into, if you just do it as you have it now, is that your values will be overridden since you have multiple inputs with the same name.
You can get around that by adding a unique ID or class to their parent container.
var inputs = document.querySelectorAll("input");
var data = {};
for (var i = 0; i < inputs.length; i++) {
data[inputs[i].name] = inputs[i].value;
}
console.log(data);
For getting a specific set of inputs, using the unique identifier I mentioned above, all you have to do is change the query selector.
var inputs = document.querySelectorAll("#container input");
EDIT
Having an unknown amount of subclasses you can put them into an array. Following the same JS above, it's just one extra step.
var subclasses = document.querySelectorAll(".slot_subclass");
var data = [];
for (var i = 0; i < subclasses.length; i++) {
if (!data[i]) data[i] = {};
var inputs = subclasses[i].querySelectorAll("input");
for (var o = 0; o < inputs.length; o++) {
data[i][inputs[o].name] = inputs[o].value;
}
}
console.log(data);
// outputs like:
[
0: {slot_name: "", slot_type: ""}
1: {slot_name: "", slot_type: ""}
2: {slot_name: "", slot_type: ""}
]

Related

How to show total value of two text box in another box - Javascript

I am new to javascript, I want to get two fees in text boxes and show sum of those two fees in another text box (which is disabled, so can't edit it, just for showing purpose) below is my html form.. result should show when entering in fee1 or fee2 not in submit button. How to do it?
<div class="row">
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id ="total_fee" name="total_fee" >
</div>
</div>
use input event on fee1 and fee2 and then sum their values and put as value of total_fee.
e.g.
const fee1 = document.getElementById("fee1");
const fee2 = document.getElementById("fee2");
const total_fee = document.getElementById("total_fee");
fee1.addEventListener("input", sum);
fee2.addEventListener("input", sum);
function sum() {
total_fee.value = Number(fee1.value)+Number(fee2.value);
}
see in action
https://jsbin.com/lizunojadi/edit?html,js,output
Basically you listen to input event on both of the controls, summing the values into the other input.
document.querySelectorAll("#fee1, #fee2").forEach(function(elem) {
elem.addEventListener("input", do_sum)
})
function do_sum() {
var total = 0
document.querySelectorAll("#fee1, #fee2").forEach(function(elem) {
total += +elem.value;
})
document.querySelector("#total_fee").value = total
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="container">
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id="total_fee" name="total_fee">
</div>
</div>
</div>
</div>
Here is the simple solution for your code,
<div class="row">
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0" value="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0" value="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id ="total_fee" name="total_fee" >
</div>
</div>
Here in the HTML code default value="0",
Now in Javascript,
const fee1 = document.getElementById('fee1');
const fee2 = document.getElementById('fee2');
const totalFee = document.getElementById('total_fee');
function doSum() {
const fee1Value = parseInt(fee1.value);
const fee2Value = parseInt(fee2.value);
const totalFeeValue = fee1Value + fee2Value;
totalFee.value = totalFeeValue;
}
fee1.addEventListener('input', doSum);
fee2.addEventListener('input', doSum);
doSum() function is executing oninput

Form validation with multiple highlighted fields

I have a registration form that I would like to have multiple field validation. What I mean by this is if more than one field is not filled in it will be highlighted red. I have some code already written but instead of highlighting the field not filled in, it's highlighting all of them. I realise it is quite long winded but I'm fairly new to this. My JS code is as follows:
`function formCheck() {
var val = document.getElementById("fillMeIn").value;
var val = document.getElementById("fillMeIn2").value;
var val = document.getElementById("fillMeIn3").value;
var val = document.getElementById("fillMeIn4").value;
var val = document.getElementById("fillMeIn5").value;
var val = document.getElementById("fillMeIn6").value;
var val = document.getElementById("fillMeIn7").value;
if (val == "") {
alert("Please fill in the missing fields");
document.getElementById("fillMeIn").style.borderColor = "red";
document.getElementById("fillMeIn2").style.borderColor = "red";
document.getElementById("fillMeIn3").style.borderColor = "red";
document.getElementById("fillMeIn4").style.borderColor = "red";
document.getElementById("fillMeIn5").style.borderColor = "red";
document.getElementById("fillMeIn6").style.borderColor = "red";
document.getElementById("fillMeIn7").style.borderColor = "red";
return false;
}
else {
document.getElementById("fillMeIn").style.borderColor = "green";
document.getElementById("fillMeIn2").style.borderColor = "green";
document.getElementById("fillMeIn3").style.borderColor = "green";
document.getElementById("fillMeIn4").style.borderColor = "green";
document.getElementById("fillMeIn5").style.borderColor = "green";
document.getElementById("fillMeIn6").style.borderColor = "green";
document.getElementById("fillMeIn7").style.borderColor = "green";
}
}`
My HTML is as follows:
'<form id="mbrForm" onsubmit="return formCheck();" action="thanks.html" method="post">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-4 vertical-gap">
FIRST NAME:
<input id="fillMeIn" type="text" class="form-control" placeholder="First Name" >
</div>
<div class="col-md-4 vertical-gap">
LAST NAME:
<input id="fillMeIn2" type="text" class="form-control" placeholder="Last Name" >
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8 vertical-gap">
ADDRESS:
<input id="fillMeIn3" type="text" class="form-control vertical-gap" placeholder="First Line" >
<input id="fillMeIn4" type="text" class="form-control vertical-gap" placeholder="Second Line" >
<input id="fillMeIn5" type="text" class="form-control vertical-gap" placeholder="Town/City" >
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-4 vertical-gap">
POST CODE:
<input id="fillMeIn6" type="text" class="form-control vertical-gap" placeholder="Postcode" >
</div>
<div class="col-md-4 vertical-gap">
PHONE No:
<input type="number" class="form-control vertical-gap" placeholder="Tel no">
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
EMAIL ADDRESS:
<input id="fillMeIn7" type="email" class="form-control vertical-gap" placeholder="Email address" >
</div>
<div class="col-md-2"></div>
</div>
<div class="row vertical-gap">
<div class="col-md-2"></div>
<div class="col-md-8">
DISCIPLINE:
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Cross Country"> CROSS COUNTRY
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Enduro"> ENDURO
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Downhill"> DOWNHILL
</label>
</div>
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-10">
<!--<button type="button" input type="hidden" class="btn btn-success" name="redirect" value="thanks.html">SUBMIT</button>-->
<input type="submit" value="SUBMIT" class="btn btn-success btn-lg">
</div>
<div class="col-md-2"></div>
</div>
</form>'
Thanks!
You could have the ids in an Array, iterate through its values, and execute the repeatable code in a function that groups all the logic inside.
example :
["fillMeIn1", "fillMeIn2", "fillMeIn3", "fillMeIn4"].each(function(id){
// do things with id
})
Why not use the html "required" property instead?
If you want to do this with JS, you should give each variable a different name. In the code you posted you are continuously overwriting the same variable, and then, it evaluates val (which ended up being assigned to the (fill me7 value) to "", and if true, setting all the borders to red.
Set different variables, push the input values into an array when submit is triggered and loop through them if variables[i]==0, set getElementId(switch case[i] or another array with the name of the inputs[i]).bordercolor to red.
AGAIN, this sound VERY INEFFICIENT and I am not sure at all it would work. My guess is that it would take A LOT of time, and probably get timed out (except you are using some asych/try-catch kind of JS).
I would simply go for an HTML required property and then override the "required" property in CSS to make it look as you intend to. Simpler, easy and clean.
The main issue in your code is that you override the variable val each time you wrote var val = ....
Keeping your own your logic, you could write something like that.
var formModule = (function () {
var $fields = [
document.getElementById('fillMeIn'),
document.getElementById('fillMeIn2'),
document.getElementById('fillMeIn3'),
document.getElementById('fillMeIn4'),
document.getElementById('fillMeIn5'),
document.getElementById('fillMeIn6'),
document.getElementById('fillMeIn7')
];
function markInvalid($field) {
$field.style.borderColor = 'red';
}
function markValid($field) {
$field.style.borderColor = 'green';
}
return {
check: function () {
var isValid = true;
$fields.forEach(function ($f) {
if ($f.value === '') {
if (isValid) alert('Please fill in the missing fields');
isValid = false;
markInvalid($f);
}
else markValid($f);
});
return isValid;
}
};
})();
There are some extra concepts in this example which may be useful:
Working with the DOM is really slow, that's why you should
put your elements in a variable once for all and not everytime you
click on the submit button.
In my example i wrap the code with var formModule = (function () {...})();.
It's called module pattern. The goal is to prevent variables to leak in the rest of the application.
A better solution could be this one using the 'power' of html form validation:
HTML:
<form id="mbrForm" action="thanks.html" method="post">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-4 vertical-gap">
FIRST NAME:
<input id="fillMeIn" type="text" required class="form-control" placeholder="First Name">
</div>
<div class="col-md-4 vertical-gap">
LAST NAME:
<input id="fillMeIn2" type="text" required class="form-control" placeholder="Last Name">
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8 vertical-gap">
ADDRESS:
<input id="fillMeIn3" type="text" required class="form-control vertical-gap" placeholder="First Line">
<input id="fillMeIn4" type="text" required class="form-control vertical-gap" placeholder="Second Line">
<input id="fillMeIn5" type="text" required class="form-control vertical-gap" placeholder="Town/City">
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-4 vertical-gap">
POST CODE:
<input id="fillMeIn6" type="text" required class="form-control vertical-gap" placeholder="Postcode">
</div>
<div class="col-md-4 vertical-gap">
PHONE No:
<input type="number" class="form-control vertical-gap" placeholder="Tel no">
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
EMAIL ADDRESS:
<input id="fillMeIn7" type="email" required class="form-control vertical-gap" placeholder="Email address">
</div>
<div class="col-md-2"></div>
</div>
<div class="row vertical-gap">
<div class="col-md-2"></div>
<div class="col-md-8">
DISCIPLINE:
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Cross Country"> CROSS COUNTRY
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Enduro"> ENDURO
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input horizontal-gap" type="checkbox" value="Downhill"> DOWNHILL
</label>
</div>
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-10">
<input id="btnSubmit" type="submit" value="SUBMIT" class="btn btn-success btn-lg">
</div>
<div class="col-md-2"></div>
</div>
</form>
JS:
var formModule = (function () {
var $form = document.getElementById('mbrForm');
var $btn = document.getElementById('btnSubmit');
var $fields = [
document.getElementById('fillMeIn'),
document.getElementById('fillMeIn2'),
document.getElementById('fillMeIn3'),
document.getElementById('fillMeIn4'),
document.getElementById('fillMeIn5'),
document.getElementById('fillMeIn6'),
document.getElementById('fillMeIn7')
];
checkValidation();
$form.addEventListener('change', checkValidation);
$form.addEventListener('keyup', checkValidation);
$fields.forEach(function ($f) {
$f.addEventListener('change', function () {
markInput($f, $f.checkValidity());
});
});
function checkValidation() {
$btn.disabled = !$form.checkValidity();
}
function markInput($field, isValid) {
$field.style.borderColor = isValid ? 'green' : 'red';
}
})();
In this example, the button gets disabled until the form is valid and inputs are validated whenever they are changed.
I added required attribute in HTML inputs so they can be handled by native javascript function checkValidity(). Note that in this case inputs email and number are also correctly checked. You could also use attribute pattern to get a more powerfull validation:
<input type="text" pattern="-?[0-9]*(\.[0-9]+)?">
Hope it helps.

Dynamically switch between field sets in html

I currently have a dropdown field that onchange will input the value.
function CurrentStatusChanged() {
var currentS1 = document.getElementById("currentStatus1").value;
var currentS2 = document.getElementById("currentStatus2").value;
document.getElementById("currentStatusView1").innerHTML = "You selected: " + currentS1;
document.getElementById("currentStatusView2").innerHTML = "You selected: " + currentS2;
}
I have many fieldsets created and then correct fieldset needs to show dependent on the what selected in the dropdown box.
My question is:
What is the best approach? As I don't feel innerHTML then all of the code is good practise.
<fieldset class="employed">
<h2>Employed</h2>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-4 control-label" for="partTime">If Part Time, please detail your contractual hours per week</label>
<div class="col-md-4">
<textarea class="form-control" id="partTime" name="partTime"></textarea>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="numberOfJobs">Number of Jobs</label>
<div class="col-md-4">
<input id="numberOfJobs" name="numberOfJobs" type="text" placeholder="" class="form-control input-md" required="">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="jobDescriptionTitle">Job Description / Title</label>
<div class="col-md-4">
<input id="jobDescriptionTitle" name="jobDescriptionTitle" type="text" placeholder="" class="form-control input-md" required="">
</div>
</div>
I am trying to add a field set like the one above to a container, however i have at least 12 that change dependent on the drop-down. kindisch answer doesn't allow mt use the complete field set but is on the right track i believe.
Use templates for that. For example:
var storage = [],
select = document.getElementById("selection"),
container = document.getElementById("container");
select.addEventListener("change", function() {
var _id = select.value,
_tpl = document.getElementById(_id);
save();
container.innerHTML = _tpl.innerHTML;
update();
}, false);
// Save current state
function save() {
var _fields = container.getElementsByClassName("form-control");
for (var i = 0; i < _fields.length; i++) {
storage[_fields[i].name] = _fields[i].value;
}
}
// Fill input fields of element
function update() {
var _fields = container.getElementsByClassName("form-control");
for (var i = 0; i < _fields.length; i++) {
if (_fields[i].name in storage) {
_fields[i].value = storage[_fields[i].name];
}
}
}
<select id="selection">
<option value="status-one">One</option>
<option value="status-two">Two</option>
<option value="status-three">Three</option>
</select>
<div id="container"></div>
<script type="text/html" id="status-one">
<fieldset class="employed">
<h2>Employed</h2>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-4 control-label" for="partTime">If Part Time, please detail your contractual hours per week</label>
<div class="col-md-4">
<textarea class="form-control" id="partTime" name="partTime"></textarea>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="numberOfJobs">Number of Jobs</label>
<div class="col-md-4">
<input id="numberOfJobs" name="numberOfJobs" type="text" placeholder="" class="form-control input-md" required="">
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="jobDescriptionTitle">Job Description / Title</label>
<div class="col-md-4">
<input id="jobDescriptionTitle" name="jobDescriptionTitle" type="text" placeholder="" class="form-control input-md" required="">
</div>
</div>
</script>
<script type="text/html" id="status-two">
<p>This is status two.</p>
</script>
<script type="text/html" id="status-three">
<p>This is status three.</p>
</script>
could you use html5 data attributes? https://jsfiddle.net/hj6bbgbd/
<select id="mySelect" onchange="myFunction()">
<option value="1" data-text = "text for choice one">One</option>
<option value="2" data-text = "text for choice two">Two</option>
<option value="3" data-text = "text for choice three">Three</option>
</select>
<fieldset>
<fieldset>
<legend>My Legend:</legend>
<p id="demo"> text for choice one </p>
</fieldset>
<script>
function myFunction() {
var sel = document.getElementById('mySelect');
var opt = sel.options[sel.selectedIndex];
document.getElementById("demo").innerHTML = opt.dataset.text;
}
</script>

ng-model not updating with input from textbox

This seems like a weird one to me. I have a form for adding vets to a dog walkers' database. I've used ng-model on each field in the form.
<div class="container-fluid" ng-show="nav.page == 'new'" ng-controller="dataController as data">
<div class="row" ng-show="nav.tab == 'vet'">
<div class="col-md-2">
</div>
<div class="col-md-8">
<h1>Add a Vet</h1>
<hr />
<form>
<div class="form-group">
<input type="text" class="form-control" placeholder="Name..." ng-model="data.creator.vet.Name"/>
</div>
<div class="form-group">
<input type="Text" class="form-control" placeholder="Address..." ng-model="data.creator.vet.Address"/>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Phone Number..." ng-model="data.creator.vet.Phone"/>
</div>
<div class="form-group">
<button class="btn btn-success" ng-click="data.newVet()">Submit</button>
</div>
</form>
</div>
<div class="col-md-2">
</div>
</div>
</div>
Yesterday it was working fine, today it won't update data.creator.vet when I input data. For the life of me, I can't see any problems with it.
The js:
app.controller('dataController', function($http) {
dataCon = this;
this.creator = {};
this.creator.client = {};
this.creator.vet = {};
this.creator.client.Dogs = [];
this.allData = {};
this.newVet = function(){
console.log("New Vet Creating....")
console.log(dataCon.creator)
vet = JSON.stringify(dataCon.creator.vet);
console.log(vet);
$http.get(SERVICE_URL + "?fn=vetCreate&vet=" + vet).then(function(response) {
dataCon.init();
});
}
});

Unable to create array of object to save MongoDB from AngularJS

I have created html dynamically and want to save in MongoDB using Mongoose from AngularJS. But the problem is that, I'm unable to create that require object which I have created Mongoose schema.
model code
var SegmentSchema = new Schema({
name: String,
uiName:String,
type:String,
lower:Number,
upper:Number,
options:[{key:String,value:String}]
});
export default mongoose.model('Segment', SegmentSchema);
view code
<form class="form-horizontal" ng-submit="addSegment()">
<div class="form-group">
<label class="col-sm-2 control-label">Name</label>
<div class="col-sm-6">
<p class="form-control-static"><input class="form-control" type="text" required ng-model="segment.name" name="name" value=""></p>
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">UI Name</label>
<div class="col-sm-6">
<input class="form-control" type="text" ng-model="segment.uiName" name="uiName" value="">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">Type</label>
<div class="col-sm-6">
<select ng-model="segment.type" ng-change="changeType()" class="form-control" name="type">
<option value="">---select type---</option>
<option value="text">Text</option>
<option value="range">Range</option>
<option value="select">Select</option>
<option value="binary">Binary</option>
</select>
</div>
</div>
<div ng-show="rangeShow" class="form-group">
<label for="lower_range" class="col-sm-2 control-label">Lower Range</label>
<div class="col-sm-6">
<input class="form-control" ng-model="segment.lower" type="number" name="lower" value="">
</div>
</div>
<div ng-show="rangeShow" class="form-group">
<label for="lower_range" class="col-sm-2 control-label">Lower Range</label>
<div class="col-sm-6">
<input class="form-control" ng-model="segment.upper" type="number" name="upper" value="">
</div>
</div>
<div ng-show="numOptionShow" class="form-group">
<label for="inputPassword" class="col-sm-6 control-label"></label>
<div class="col-sm-2">
<input placeholder="Options count" class="form-control col-sm-3" ng-keydown="keyupOptionNumber()" ng-keyup="keyupOptionNumber()" ng-model="numOption" type="text" value="">
</div>
</div>
<div ng-show="selectOptionShow" class="" id="segment-select-option">
</div>
<div class="form-group">
<button type="submit" ng-show="addSegmentBtn" class="btn btn-success">Add</button>
</div>
</form>
angularjs(controller) code:
angular.module('nrichApp')
.controller('SegmentCtrl', function ($scope,$http,segment) {
$scope.loading = true;
$scope.addSegmentDiv=false;
segment.get().success(function(data) {
$scope.segments=data;
});
$scope.loading = false;
})
.controller('AddSegmentCtrl', function ($scope,segment,$location,$compile) {
$scope.loading = true;
$scope.addSegmentBtn=false;
$scope.changeType=function(){
$scope.addSegmentBtn=true;
$scope.rangeShow=false;
$scope.selectOptionShow=false;
$scope.numOptionShow=false;
switch ($scope.segment.type) {
case 'range':
$scope.rangeShow=true;
break;
case 'select':
$scope.numOptionShow=true;
break;
case 'binary':
break;
default:
}
};
$scope.keyupOptionNumber=function(){
console.log($scope.numOption);
$scope.selectOptionShow=true;
var input ='';
for (var i = 0; i < $scope.numOption; i++) {
input+='<div class="form-group">';
input+='<label for="option_key" class="col-sm-2 control-label">Key</label>';
input+='<div class="col-sm-2"><input ng-model="segment.options[' + i + '].key" class="form-control" type="text" name="key" value=""></div>';
input+='<label for="option_value" class="col-sm-1 control-label">Value</label>';
input+='<div class="col-sm-3"><input ng-model="segment.options[' + i + '].value" class="form-control" type="text" name="value" value=""></div>';
input+='</div>';
}
var eleDiv=angular.element(document.querySelector('#segment-select-option'));
eleDiv.html(input);
$compile(eleDiv)($scope);
};
$scope.addSegment=function(){
$scope.loading = true;
var param = {'segment' : $scope.segment};
console.log(JSON.stringify(param));//it is output which show at below
segment.create(param)
.success(function(data) {
$scope.loading = false;
$location.path('/segment');
});
$scope.loading = false;
};
});
Output:
{
"segment":{
"type":"select",
"name":"range2",
"uiName":"Select 3",
"options":{
"0": { "key":"k3","value":"v2"},
"1": { "key":"k4","value":"v4"}
}
}
}
Desired Output:
{
"segment": {
"type":"select",
"name":"range2",
"uiName":"Select 3",
"options": [
{"key":"k3","value":"v2"},
{"key":"k4","value":"v4"}
]
}
}
Finally, i got solution. I just declare array data type for options variable i.e,
$scope.options=[]
Inside angular controller:
$scope.keyupOptionNumber=function(){
$scope.options=[];//Here, this line is missing
console.log($scope.numOption);
$scope.selectOptionShow=true;
var input ='';
for (var i = 0; i < $scope.numOption; i++) {
input+='<div class="form-group">';
input+='<label for="option_key" class="col-sm-2 control-label">Key</label>';
input+='<div class="col-sm-2"><input ng-model="segment.options[' + i + '].key" class="form-control" type="text" name="key" value=""></div>';
input+='<label for="option_value" class="col-sm-1 control-label">Value</label>';
input+='<div class="col-sm-3"><input ng-model="segment.options[' + i + '].value" class="form-control" type="text" name="value" value=""></div>';
input+='</div>';
}
var eleDiv=angular.element(document.querySelector('#segment-select-option'));
eleDiv.html(input);
$compile(eleDiv)($scope);
};
Thanks #shaishab roy

Categories