Issue with multi dimensional becoming empty after assigning to var - javascript

I'm having a very strange issue with javascript where I'm building a multi dimensional array and somehow it's being emptied to [[]] on var assignment.
The target being passed to the buildFormObject function is a html form element.
if (!Element.prototype.closest) {
Element.prototype.closest = function(s) {
var el = this;
if (!document.documentElement.contains(el)) return null;
do {
if (el.matches(s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
var submit = document.getElementsByClassName('submit');
submitForm_click(submit);
function submitForm_click (trigger) {
if (trigger.length > 0) {
for (var t of trigger) {
t.addEventListener('click', function (e) {
e.preventDefault();
submitForm(t.parentNode);
});
}
} else {
trigger.addEventListener('click', function (e) {
e.preventDefault();
submitForm(trigger.parentNode);
});
}
}
function submitForm (target) {
var info = buildFormObject(target);
console.log(buildFormObject(target));
console.log(info);
}
function buildFormObject (target) {
var inputs = target.querySelectorAll('input,select');
var results = [];
var multi = [];
var iter = 0;
var pos = 0;
for (var input of inputs) {
if (iter > 0) {
iter = iter - 1;
continue;
}
if (input.parentNode.closest('.multiInput') != null) {
var obj = [];
var parent = input.parentNode.closest('.multiInput');
var children = parent.querySelectorAll('input,select');
for (var i of children) {
if (checkIfValueExist(i, i.type)) {
obj[i.name] = i.value;
}
}
multi[pos] = obj;
results[parent.attributes.name.nodeValue] = multi;
pos = pos + 1;
iter = children.length-1;
} else if (checkIfValueExist(input, input.type)) {
results[input.name] = input.value;
pos = 0;
multi = [];
}
}
return results;
}
function checkIfValueExist (target, type) {
switch (type) {
case 'text':
return (target.value == "" ? false : true);
break;
case 'select-one':
return (target.value == "" ? false : true);
break;
case 'checkbox':
return (target.checked === false ? false : true);
break;
case 'radio':
return (target.checked === false ? false : true);
break;
case 'button':
return false;
break;
case 'submit':
return false;
break;
default:
return true;
break;
}
}
<form id="ct">
<input type="hidden" name="task" value="createTable"/>
<div id="tableSection" class="flexContainer">
<div class="block">
<label for="dbName">Select Database</label>
<select name="dbName" class="dbList" required>
<option value="" disabled selected>Please Select</option>
<option value="1">test</option>
</select>
</div>
<div class="block">
<label for="tableName">Table Name</label>
<input type="text" name="tableName" required/>
</div>
</div>
<div class="row flexContainer multiInput" name="tableRow">
<div class="trColumn">
<label for="columnName">Name</label>
<input type="text" name="columnName" required/>
</div>
<div class="trColumn">
<label for="columnType">DataType</label>
<select name="columnType" required>
<option value="" disabled selected>Please Select</option>
<option value="1">CHAR</option>
</select>
</div>
<div class="trColumn">
<label for="columnLength">Length</label>
<input type="text" name="columnLength"/>
</div>
<div class="trColumn">
<label for="columnPK">PK</label>
<input type="checkbox" name="columnPK" value="1"/>
</div>
<div class="trColumn">
<label for="columnDefault">DefaultValue</label>
<input type="text" name="columnDefault"/>
</div>
</div>
<input type="button" class="submit" value="Submit" />
</form>
Result 1:
[task: "createDBTable", dbName: "1", tableName: "tester", tableRow: Array(1)]
dbName: "1"
tableName: "tester"
tableRow: [Array(0)]
task: "createDBTable"
length: 0
__proto__: Array(0)
Result 2:
[task: "createDBTable", dbName: "1", tableName: "tester", tableRow: Array(1)]
dbName: "1"
tableName: "tester"
tableRow: "[[]]"
task: "createDBTable"
length: 0
__proto__: Array(0)
What I don't understand is why the tableRow is going from an Array(6) value to [[]] just because I setting the original variable, the returned value from the buildFormObject function, to a variable.
ADDITIONAL INFORMATION
In the code snippet above I have included the code I'm working with. There seems to be a small quirk where the console.log is only showing [], but you you type one of the property names that should be there like, "tableName"then you can access the value. This isn't true for the problem property of "tableRow" since the nested array is showing as []. I'm not sure if it's the testing software, but if you try it on a local test environment then you shouldn't have any issues seeing what my initial problem is.

Related

How to check for specific object key and update if exists

I have text inputs that are writing to a model. I want those objects to write to the model and update if the key exists.
For example: If I submit,
Id: "1", Value: "Foo"
And I update it with a new value:
Id: "1", Value: "Bar"
My array should read:
0 { Id: "1", Value: "Bar"}
Not
0 { Id: "1", Value: "Foo"}
1 { Id: "1", Value: "Bar"}
Example here: JSFiddle
<div id="wrapper">
<div>
<input id="1" type="text" value="input_1">
<button>Button 1</button>
</div>
<br>
<div>
<input id="2" type="text" value="input_2">
<button>Button 2</button>
</div>
<br>
<div>
<input id="3" type="text" value="input_3">
<button>Button 3</button>
</div>
<br>
</div>
jQuery -- will add to the array but not sure how to update if key exists. Looked at other examples but still not getting it
var obj = {
pairs: []
}
$("button").on("click", function() {
var keyValuePairs = {
id: "",
value: ""
}
var input_id = $(this).prev().prop('id');
var dynamic_value = $(this).prev().prop('value');
if(obj.pairs.length > 0){
$.each(obj.pairs, function(i, pair) {
if($(this).id !== input_id){
obj.pairs.push(keyValuePairs);
return false;
} else {
obj.pairs.splice(i, 1);
obj.pairs.push(keyValuePairs);
}
});
} else {
obj.pairs.push(keyValuePairs);
}
keyValuePairs.id = input_id;
keyValuePairs.value = dynamic_value;
console.log(obj);
});
Try this https://jsfiddle.net/y6rgm7z8/93/
$(document).ready(function() {
var obj = {
pairs: []
}
$("button").on("click", function() {
var keyValuePairs = {
id: "",
value: ""
}
var input_id = $(this).prev().prop('id');
var dynamic_value = $(this).prev().prop('value');
var pair = obj.pairs.find(item => item.id === input_id)
if(pair){
pair.value = dynamic_value;
} else {
keyValuePairs.id = input_id;
keyValuePairs.value = dynamic_value;
obj.pairs.push(keyValuePairs);
}
console.log(obj);
});
});
The find() method executes the function once for each element present in the array:
If it finds an array element where the function returns a true value, find() returns the value of that array element (and does not check the remaining values)
Otherwise it returns undefined
The find() is better for performance than each().
And we don't need splice() with push() for updating because after find() we have link to the object, so we can change the value.
If find() returns undefined we will push the new object to the array
See if this helps
$(document).ready(function() {
var obj = {
pairs: []
}
$("button").on("click", function() {
var found = false;
var input_id = $(this).prev().prop('id');
var dynamic_value = $(this).prev().prop('value');
var keyValuePairs = {
id: input_id,
value: dynamic_value
}
if(obj.pairs.length > 0){
$.each(obj.pairs, function(i, pair) {
if(pair[Object.keys(pair)[0]] === input_id){
obj.pairs[i] = keyValuePairs;
found = true;
return false;
}
});
if(!found)
obj.pairs.push(keyValuePairs);
} else {
obj.pairs.push(keyValuePairs);
}
console.log(obj);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div>
<input id="1"type="text" value="input_1">
<button>Button 1</button>
</div>
<br>
<div>
<input id="2" type="text" value="input_2">
<button>Button 2</button>
</div>
<br>
<div>
<input id="3" type="text" value="input_3">
<button>Button 3</button>
</div>
<br>
</div>
I finally changed a lot...
I used a flag to know if the update was done...
So I run the .each() loop first. It doesn't run if there is no key/pair already. Then a comparison if the change was not yet done, to push a new value.
var obj = {
pairs: []
}
$("button").on("click", function() {
var keyValuePairs = {
id: "",
value: ""
}
var change_done=false;
var input_id = $(this).prev().prop('id');
var dynamic_value = $(this).prev().prop('value');
$.each(obj.pairs, function(i, pair) {
if(obj.pairs[i].id == input_id){ // Change is here.
obj.pairs[i].id=input_id;
obj.pairs[i].value=dynamic_value;
change_done=true;
return false;
}
});
if(!change_done || obj.pairs.length == 0){
obj.pairs.push(keyValuePairs);
}
keyValuePairs.id = input_id;
keyValuePairs.value = dynamic_value;
console.log(obj);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div>
<input id="1 "type="text" value="input_1">
<button>Button 1</button>
</div>
<br>
<div>
<input id="2" type="text" value="input_2">
<button>Button 2</button>
</div>
<br>
<div>
<input id="3" type="text" value="input_3">
<button>Button 3</button>
</div>
<br>
</div>
I have rewritten a bit. If ID exists, its value will be updated and new row will not be inserted:
$(document).ready(function() {
var obj = {
pairs: []
}
$("button").on("click", function() {
var input_id = $(this).prev().prop('id');
var dynamic_value = $(this).prev().prop('value');
var isUpdated = false;
var keyValuePairs = {
id: input_id,
value: dynamic_value
};
if (obj.pairs.length == 0) {
obj.pairs.push(keyValuePairs);
return false;
}
$.each(obj.pairs, function(i, pair) {
if (obj.pairs[i].id === input_id) {
obj.pairs[i].value = dynamic_value;
isUpdated = true;
return false;
}
});
if (!isUpdated) {
obj.pairs.push(keyValuePairs);
}
console.log(obj);
});
});
Tested and it works.
You can do it like this:
const pair = obj.pairs.find(pair => pair.id === input_id);
if (pair) {
obj.pairs[input_id] = {...keyValuePairs}
} else {
obj.pairs.push(keyValuePairs)
}

Angularjs devade tags when user put comma

I have a case in which I need to divide tags when the user put a comma separation, for the moment the user can only add tags one by one, what I want to do is allows user to enter more than one tag in the input separated by a comma:
This is what I have now :
this is what I want to do :
what I have so far :
<div class="form-group">
<label>Mes centres d'intérêt</label>
<div class="input-group" style="margin-bottom: 8px;">
<input id="tagInsert" type="text" name="newTag" ng-model="newTag" ng-model-options="{debounce: 100}" typeahead="tag for tag in getTags($viewValue)" class="form-control" typeahead-loading="loadingTags" ng-keydown="addInterestOnEvent($event)" ng-disabled="interestLimit" autocomplete="off">
<span class="input-group-btn"><span class="btn btn-primary" ng-click="addInterest()" analytics-on="click" ng-disabled="interestLimit" analytics-event="Ajout Interet" analytics-category="Profil">Ajouter</span></span>
</div>
<p class="form__field__error" ng-show="interestLimit">Vous avez atteint la limite de 10 centres d'intérêt.</p>
<ul class="tags">
<li class="tag" ng-repeat="name in user.interests track by $index">{{ name }} <i class="icon-close" ng-click="removeInterest($index)" analytics-on analytics-event="Supprimer Interet" analytics-category="Profil"></i></li>
</ul>
</div>
My controller :
$scope.getTags = function (name) {
return $http.get('/api/tags/' + name.replace('/', '')).then(function (result) {
var tags = result.data;
for (var i = tags.length; i--; ) {
var tagName = tags[i].name;
if ($scope.user.interests.indexOf(tagName) !== -1) tags.splice(i, 1);
else tags[i] = tagName;
}
return tags;
});
};
$scope.removeInterest = function (id) {
$scope.interestLimit = false;
$scope.user.interests.splice(id, 1);
}
$scope.addInterest = function () {
if ($scope.interestLimit) return;
var element = $document[0].getElementById('tagInsert'),
value = element.value;
if (value.length) {
element.value = '';
if ($scope.user.interests.indexOf(value) === -1) {
$scope.user.interests.push(value);
$scope.interestLimit = $scope.user.interests.length === 10;
}
}
};
$scope.addInterestOnEvent = function (event) {
if (event.which !== 13) return;
event.preventDefault();
$scope.addInterest();
};
$scope.remove = function () {
$scope.confirmModal = Modal.confirm.delete(function () {
User.remove(function () {
submit = true;
Auth.logout();
$location.path('/');
});
})('votre compte');
};
You should split value with comma and do for loop.
Change "addInterest" function like this:
$scope.addInterest = function () {
if ($scope.interestLimit) return;
var element = $document[0].getElementById('tagInsert'),
value = element.value.split(',');
if (value.length) {
element.value = '';
for (var i = 0; i < value.length; i++) {
if ($scope.interestLimit) break;
if ($scope.user.interests.indexOf(value[i]) === -1) {
$scope.user.interests.push(value[i]);
$scope.interestLimit = $scope.user.interests.length === 10;
}
}
}
};
As far as I understand , you want to split text into string array by comma
Try this code please
<input id='tags' type="text" />
<input type="button" value="Click" onclick="seperateText()" />
<script>
function seperateText(){
var text= document.getElementById("tags").value;
var tags = text.split(',');
console.log(text);
console.log(tags);
}
</script>

Defining JSON dynamically - can't find what I am doing wrong

I am trying to put form content in a JSON dynamically.
It worked before, but after I added a extra layer (arrays in arrays) there seem to be something that I am doing wrong:
aJSON = {};
aJSON['properties'] = [];
aJSON['options'] = [];
aJSON['arrays'] = [];
$('input').each(function () {
if($(this).attr('name') != undefined) {
if($(this).attr('name').indexOf('[]') > -1) {
if(aJSON['arrays'][$(this).attr('name')] == undefined) {
aJSON['arrays'][$(this).attr('name')] = [];
}
if($(this).is(':checked')) {
aJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 1;
} else {
aJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 0;
}
} else {
aJSON['properties'][$(this).attr('name')] = $(this).val();
}
}
});
$('select').each(function () {
if($(this).attr('name') != undefined) {
aJSON['properties'][$(this).attr('name')] = $(this).val();
}
});
var array = getUrlVars();
aJSON['options']['type'] = array['type'];
aJSON['options']['id'] = array['id'];
aJSON['options']['view'] = pageSpecificVariables['view'];
The top 4 lines are just a tryout, I also tried:
aJSON = {'properties':[], 'options':[], 'arrays':[]}
But the only result I am getting is an object with empty arrays of properties, options and arrays.
Before I put all the values directly in aJSON and that worked perfectly.
But for categorizing, I need the 3 categories to exist.
Any idea why my values aren't written to the aJSON?
EDIT
Added JSfiddle here: http://jsfiddle.net/abayob/pob32fs1/
I assume you are trying to serialise a form.
Use jQuery's serializeArray function instead
var myform = $("#myform");
var data = JSON.stringify( myform.serializeArray() );
Update
Because you're trying to use arrays like object-maps
Solution: http://jsfiddle.net/pob32fs1/8/
var oJSON = {
properties: {},
options: {},
arrays: {}
};
$('input[name]').each(function(){
var $el = $(this),
value = $el.attr("value"),
name = $el.attr('name');
if(name.indexOf('[]') >= 0)
{
oJSON.arrays[name] = oJSON.arrays[name] || {};
oJSON.arrays[name][value] = $el.is(':checked') ? 1 : 0;
} else {
oJSON.properties[name] = $el.val();
}
});
$('select[name]').each(function(){
var $el = $(this);
oJSON.properties[$el.attr('name')] = $el.val();
});
oJSON.options['type'] = 'user';
oJSON.options['id'] = 1;
oJSON.options['view'] = 'user-settings';
console.log(oJSON);
Assuming that the name and value attributes of your various inputs are strings, and not just numbers, you should be using nested objects, not nested arrays. You're trying to use associative arrays, which are not available in JavaScript.
var oJSON = {};
$('._save, .btn-success').click(function() {
oJSON = {
properties: {},
options: {},
arrays: {}
};
$('input').each(function() {
if ($(this).attr('name') != undefined) {
if ($(this).attr('name').indexOf('[]') > -1) {
if (oJSON['arrays'][$(this).attr('name')] == undefined) {
oJSON['arrays'][$(this).attr('name')] = {};
}
if ($(this).is(':checked')) {
oJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 1;
} else {
oJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 0;
}
} else {
oJSON['properties'][$(this).attr('name')] = $(this).val();
}
}
});
$('select').each(function() {
if ($(this).attr('name') != undefined) {
oJSON['properties'][$(this).attr('name')] = $(this).val();
}
});
oJSON['options']['type'] = 'user';
oJSON['options']['id'] = 1;
oJSON['options']['view'] = 'user-settings';
console.log(oJSON);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="tab-content">
<div id="tab-general" class="tab-pane active">
<h4>Gebruikersnaam</h4>
<input type="text" value="John Doe" name="username" class="form-control" required="" placeholder="J. Average">
<h4>E-mailadres</h4>
<input type="email" value="info#info.info" name="mailaddress" class="form-control" required="" placeholder="E-mail#adres.nl">
<div class="row">
<div class="col-md-6">
<input type="password" name="password" minlength="10" class="form-control" placeholder="Nieuw wachtwoord">
</div>
<div class="col-md-6">
<input type="password" name="password_retype" minlength="10" class="form-control" placeholder="Herhaal wachtwoord">
</div>
</div>
<input type="password" name="password_old" class="form-control margin-y-10" placeholder="Huidig Wachtwoord">
</div>
<div id="tab-sites" class="tab-pane">
<h4>Websites</h4>
<div id="site_container">
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="0">
<label>A</label>
</div>
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="1">
<label>B</label>
</div>
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="2">
<label>C</label>
</div>
</div>
</div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-warning _cancel">Annuleren</button>
<button type="button" class="btn btn-success _save">Opslaan</button>
</div>

Finding closest input text after select dropdown was chosen

So what I'm trying to do is change value of the input with id championSpell[] whenever something from dropdown select name="change[]" id="change[] is chosen. Inputs are generated dynamically. Test variable in function val() is responsible for that change and is the one I have problems with.
<script src="LeagueNotes/js/jquery.min.js"></script>
<script src="LeagueNotes/js/champions_list.js"></script>
<script src="LeagueNotes/js/jquery.validate.min.js"></script>
<style>
* { font-family:Arial; }
h2 { padding:0 0 5px 5px; }
h2 a { color: #224f99; }
a { color:#999; text-decoration: none; }
a:hover { color:#802727; }
p { padding:0 0 5px 0; }
input { padding:5px; border:1px solid #999; border-radius:4px; -moz-border-radius:4px; -web-kit-border-radius:4px; -khtml-border-radius:4px; }
</style>
<h2>
Add Another Champion
</h2>
<form name="second_form" id="second_form" action="#" method="POST" style="margin: 0;" >
<div id="p_scents">
<p>
<label for="p_scnts">
<input type="text" id="champion[]" size="20" list="champions" value="" placeholder="Enter Champion's name">
<datalist id="champions"></datalist>
Add General Change<a></a>
Add Spell<a></a>
</label>
</p>
</div>
<br/><input type="submit" value="submit">
</form>
<script>
for(var key in champions){
if(champions.hasOwnProperty(key)){
$('#champions').append('<option value="' + key + '">');
}
}
var config = {
fillAll: true
};
document.forms["second_form"].oninput = function(e) {
var champion = this["champion[]"];
//Force into array
if (champion[0] === undefined)
champion = [this["champion[]"]];
var reached = {
valid: 0,
unique: 0
};
var inputs = [].map.call(champion, function(n) {
return n.value
}).filter(function(n) {
return n.length
});
var valid = [].every.call(champion, function(n, i) {
n.setCustomValidity("");
if (config.fillAll) return (reached.valid = i, champions.hasOwnProperty(n.value));
else return n.value ? (
reached.valid = i,
champions.hasOwnProperty(n.value) > -1
) : true;
});
var unique = inputs.slice(0).sort().every(function(n, i, a) {
reached.unique = inputs.lastIndexOf(n);
return n != a[i - 1];
});
//Check for valid champions
if (!valid) {
champion[reached.valid].setCustomValidity("This is not a valid champion, please correct this field and resubmit.")
}
//Check for duplicates
if (!unique) {
champion[reached.unique].setCustomValidity("This champion has already been entered.")
}
this.checkValidity();
};
function change(x, dblchamp){
if(dblchamp===true){
if(x==="Passive"){x=0;}
if(x==="Q"){x=1;}
if(x==="Q2"){x=2;}
if(x==="W"){x=3;}
if(x==="W2"){x=4;}
if(x==="E"){x=5;}
if(x==="E2"){x=6;}
if(x==="R"){x=7;}
if(x==="R2"){x=8;}
}else if(dblchamp===false){
if(x==="Passive"){x=0;}
if(x==="Q"){x=1;}
if(x==="W"){x=2;}
if(x==="E"){x=3;}
if(x==="R"){x=4;}
}
console.log(x);
return x;
}
function val(elm) {
var championsWithExtraSpells = ["Aatrox", "Elise", "Fizz", "Heimerdinger", "Jayce", "Lee Sin", "Nidalee", "Rek'Sai","Twisted Fate"];
//var championName = $("#change").closest('input').val();
//var championName =$("#champion\\[\\]").val();
var championName = $(elm).closest("label").find("input").val();
//document.getElementById("champion[]").value;
console.log(championName);
if($.inArray(championName, championsWithExtraSpells)==-1){
var existsInArray = false;}
else{
var existsInArray = true;}
var d = $(elm).val();
var spellname = document.getElementById("championSpell[]");
var z = champions[""+championName+""][change(d, existsInArray)];
test = $(elm).nextAll("input").first().val('test');
test.value=champions[""+championName+""][change(d, existsInArray)];
}
$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents label').size() + 1;
var j =0;
$('body').on('click', '#addChampion', function() {
$('<p>Remove<br><label for="p_scnts"><input type="text" id="champion[]" size="20" list="champions" name="champion[]" value="" placeholder="Enter Champion\'s name" /><datalist id="champions"></datalist>Add General Change Add Spell<a></a></label></p>').appendTo(scntDiv);
i++;
return false;
});
$('body').on('click', '#remScnt', function() {
if( i >2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
$('body').on('click', '#addGeneral',function() {
$(
'<p><label for="var"><textarea type="text" id="champion[]" size="20" name="GeneralChange[]" value="" placeholder="Enter Description" /><select><option value="buff">Buff</option><option value="nerf">Nerf</option><option value="new">New</option><option value="change">Change</option><option value="bugfix">Bugfix</option></select></label> Remove Change</p>').appendTo($(this).next());
j++;
return false;
});
$('body').on('click', '#remVar',function() {
$(this).parent('p').remove();
return false;
});
$('body').on('click', '#addSpell',function() {
$(
'<p><select name="change[]" id="change[]" onchange="val(this)"><option value="Passive">Passive</option><option value="Q" selected>Q</option><option value="W">W</option><option value="E">E</option><option value="R">R</option></select><label for="var"><input type="text" id="championSpell[]" readOnly="true"><br><textarea type="text" id="p_scnt" size="20" name="p_scnt_' + i +'" value="" placeholder="Enter Description" /><select><option value="buff">Buff</option><option value="nerf">Nerf</option><option value="new">New</option><option value="change">Change</option><option value="bugfix">Bugfix</option></select></label> Add Change Remove Spell</p>').appendTo($(this).next());
return false;
});
});
</script>
Your post is really confusing but if you're trying to get the value of an input text witch is at the same time your drop-down menu and can contains different values. You just need to use a select function in your jQuery code.
Something similar to this:
$('#dropdown :selected').text();
You could use a change method alongside with a switch statement, something like this:
HTML:
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<input type="text" id="champion" size="20" list="champions" value="" placeholder="Enter Champion's name">
jQuery
var inputValue;
$('select').on('change', function() {
var selectedValue = $(this).val();
switch(selectedValue) {
case 'volvo':
inputValue = 'volvo';
break;
case 'saab':
inputValue = 'saab';
break;
case 'mercedes':
inputValue = 'mercedes';
break;
case 'audi':
inputValue = 'audi';
break;
default:
break;
}
$('#champion').val(inputValue);
});
Here is a working example:
http://jsfiddle.net/5spaa6kj/

Delete row dynamically in JavaScript

I'm doing a form (a simple WEB form, based on the scripts from Tom Negrino, JavaScript 8, and w3Schools) where the user press the Submit button and some of the fields from the form are displayed in one table under the form.
This is the result
Form
Now, I want to delete the row , but only the row that the user wants to delete clicking on the corresponding row.
This is my JavaScript
window.onload = initForms;
function initForms() {
for (var i=0; i< document.forms.length; i++) {
document.forms[i].onsubmit = validForm;
}
document.getElementById("sunroof").onclick = doorSet;
document.getElementById("estado").selectedIndex = 0;
document.getElementById("estado").onchange = populateDays;
/***********/
//document.getElementsByTagName("form")[0].onsubmit = addNode;
/***********/
document.getElementById("env").onclick = function() {
myFunction()
};
}
function validForm() {
var allGood = true;
var allTags = document.getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
if (!validTag(allTags[i])) {
allGood = false;
}
}
return allGood;
function validTag(thisTag) {
var outClass = "";
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
outClass += validBasedOnClass(allClasses[j]) + " ";
}
thisTag.className = outClass;
if (outClass.indexOf("invalid") > -1) {
invalidLabel(thisTag.parentNode);
thisTag.focus();
if (thisTag.nodeName == "INPUT") {
thisTag.select();
}
return false;
}
return true;
function validBasedOnClass(thisClass) {
var classBack = "";
switch(thisClass) {
case "":
case "invalid":
break;
case "reqd":
if (allGood && thisTag.value == "") {
classBack = "invalid ";
}
classBack += thisClass;
break;
case "radio":
if (allGood && !radioPicked(thisTag.name)) {
classBack = "invalid ";
}
classBack += thisClass;
break;
case "email":
if (allGood && !validEmail(thisTag.value)) classBack = "invalid ";
break;
case "isNum":
case "isZip":
classBack += thisClass;
break;
default:
if (allGood && !crossCheck(thisTag,thisClass)) {
classBack = "invalid ";
}
classBack += thisClass;
}
return classBack;
}
function crossCheck(inTag,otherFieldID) {
if (!document.getElementById(otherFieldID)) {
return false;
}
return (inTag.value != "" || document.getElementById(otherFieldID).value != "");
}
function validEmail(email) {
var re = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(email);
}
function radioPicked(radioName) {
var radioSet = "";
for (var k=0; k<document.forms.length; k++) {
if (!radioSet) {
radioSet = document.forms[k][radioName];
}
}
if (!radioSet) {
return false;
}
for (k=0; k<radioSet.length; k++) {
if (radioSet[k].checked) {
return true;
}
}
return false;
}
/****Veamos si esto funciona****/
/*function checkboxPicked(checkboxName) {
var checkboxSet = "";
for (var k = 0; k < document.forms.length; k++) {
if (!checkboxSet) {
checkboxSet = document.forms[k][checkboxName];
}
}
if (!checkboxSet) {
return false;
}
for ( k = 0; k < checkboxSet.length; k++) {
if (checkboxSet[k].checked) {
return true;
}
}
return false;
}*/
/*****************************************/
function invalidLabel(parentTag) {
if (parentTag.nodeName == "LABEL") {
parentTag.className += " invalid";
}
}
}
}
function populateDays() {
var tamps = new Array("Ikon Hatch", "Fiesta", "Focus", "Mustang");
var nvoleon = new Array("Aveo", "Spark");
var slp = new Array("Gol", "CrossFox", "Clasico", "Jetta");
var estado = document.getElementById("estado");
var estadoStr = estado.options[estado.selectedIndex].value;
if (estadoStr != "") {
var valueEst = parseInt(estadoStr);
document.getElementById("ciudad").options.length = 0;
if (valueEst == 0) {
for (var i = 0; i < tamps.length; i++) {
document.getElementById("ciudad").options[i] = new Option(tamps[i]);
}
} else if (valueEst == 1) {
for (var i = 0; i < nvoleon.length; i++) {
document.getElementById("ciudad").options[i] = new Option(nvoleon[i]);
}
} else if (valueEst == 2) {
for (var i = 0; i < slp.length; i++) {
document.getElementById("ciudad").options[i] = new Option(slp[i]);
}
}
} else {
document.getElementById("ciudad").options.length = 0;
document.getElementById("ciudad").options[0] = new Option("Model");
}
}
function doorSet() {
if (this.checked) {
document.getElementById("twoDoor").checked = true;
}
}
/*****************************/
/*function addNode() {
var inText = document.getElementById("estado").value;
var inText1 = document.getElementById("ciudad").value;
var newText = document.createTextNode(inText);
var newText1 = document.createTextNode(inText1);
var newGraf = document.createElement("table");
newGraf.appendChild(newText);
newGraf.appendChild(newText1);
var docBody = document.getElementsByTagName("body")[0];
docBody.appendChild(newGraf);
return false;
}*/
function myFunction() {
var table = document.getElementById("myTable");
var email= document.getElementById("emailAddr").value;
var brand=document.getElementById("estado").value;
var model=document.getElementById("ciudad").value;
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = email;
cell2.innerHTML = model;
cell3.innerHTML = brand;
}
And my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formulario</title>
<link rel="stylesheet" href="css/script06.css">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/bootstrap-3.2.0-dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-3.2.0-dist/css/bootstrap-theme.min.css">
<!--No se te olvide el css-->
<!--<link rel="stylesheet" href="css/bootstrap-3.2.0-dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-3.2.0-dist/css/bootstrap-theme.min.css">-->
<script src="js/script08.js"></script>
<!--No se te olvide el js-->
</head>
<body>
<header></header>
<main>
<article>
<p>
<h1>Choose your car</h1>
</p>
</article>
<form action="#">
<p>
<label for="emailAddr">Email Address:
<input id="emailAddr" type="text" size="40" class="reqd email">
</label>
</p>
<p>
<label for="passwd1">Password:
<input type="password" id="passwd1" class="reqd">
</label>
</p>
<p>
<label for="passwd2">Repeat Pass:
<input type="password" id="passwd2" class="reqd passwd1">
</label>
</p>
<!--<p>
<label for="color">Colors:
<select id="color" class="reqd">
<option value="" selected>Choose a color</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select> </label>
</p>-->
<p>
Options: <label for="sunroof">
<input type="checkbox" id="sunroof" value="Yes">
Sunroof (Two door only)</label>
<label for="pWindows">
<input type="checkbox" id="pWindows" value="Yes">
Power Windows</label>
</p>
<p>
Doors: <label for="DoorCt"><!--Doors: -->
<input type="radio" id="twoDoor" name="DoorCt" value="twoDoor" class="radio">
Two</label>
<label for="DoorCt">
<input type="radio" id="fourDoor" name="DoorCt" value="fourDoor" class="radio">
Four </label>
</p>
<p>
<label>Brand:</label>
<select id="estado" class="reqd">
<option value="">Brand</option>
<option value="0">Ford</option>
<option value="1">Chevrolet</option>
<option value="2">Volkswagen</option>
</select>
<select id="ciudad" class="reqd">
<option>Model</option>
</select>
</p>
<p>
<input type="submit" value="Enviar" id="env">
<input type="reset">
</p>
</form>
<br />
<!--Veamos si funciona-->
<table id="myTable">
<tr>
<td>Email</td>
<td>Model</td>
<td>ID Brand</td>
</tr>
<tr>
</tr>
</table>
</main>
<footer></footer>
</body>
</html>
I tried adding and extra cell in the JavaScript:
cell4.innerHTML = <button onclick="myDeleteFunction()">Del</button>;
where calls the function
function myDeleteFunction() {
document.getElementById("myTable").deleteRow();
}
to delete to row, but it didn't work.
I'll appreciate any help. Thanks.
var node = nodes[0];
if (univArray[z].ownership != "public") {
node.parentNode.removeChild(node)
}
If you want to delete a table row based on a click on the row, you can use something like:
<tr onclick="this.parentNode.removeChild(this)">
If you want to do that based on a button in the row, then:
<tr>
<td><button onclick="deleteRow(this)">Delete this row</button>
Then the deleteRow function is:
function deleteRow(element) {
var row = upTo(element, 'tr');
if (row) row.parentNode.removeChild(row);
}
A helper function
// Return first ancestor of el with tagName
// or undefined if not found
function upTo(el, tagName) {
tagName = tagName.toLowerCase();
while (el && el.parentNode) {
el = el.parentNode;
if (el.tagName && el.tagName.toLowerCase() == tagName) {
return el;
}
}
// Many DOM methods return null if they don't
// find the element they are searching for
// It would be OK to omit the following and just
// return undefined
return null;
}
The deleteRow function can be put anywhere inside a row, and the row can be in any type of table section element (head, body or foot). All you need to do is to pass a reference to any element inside the row (button, checkbox, cell, whatever).
The trouble with the table.deleteRow method is that you have to know the row index in the element that you're calling the method on. Rows have a rowIndex property that is their index in the table they are in, so you have to go up to the table to use that (i.e. row.parentNode.parentNode), whereas using the removeChild method doesn't require you to work out where in the table the row is, or to even know whether the parent is a head, body or foot section.
Edit
To add the listener dynamically, you can slightly modify the function and add a class to the buttons that will delete rows, e.g.
<!-- Sample markup -->
<table>
<tr>
<td><input type="button" class="rowDeleter" value="Delete Row">
<tr>
<td><input type="button" class="rowDeleter" value="Delete Row">
<tr>
<td><input type="button" class="rowDeleter" value="Delete Row">
</table>
Adding a class means you can easily identify the elements to add the listener to.
<script>
window.onload = function() {
// querySelectorAll and addEventListener require IE 8 or higher, use some other
// method if support for older browsers is required
var els = document.querySelectorAll('.rowDeleter');
for (var i=0, iLen=els.length; i<iLen; i++) {
els[i].addEventListener('click', deleteRow, false);
}
}
// When attached using addEventListener, this in the function
// will be the element that called the listener
function deleteRow() {
var row = upTo(this, 'tr');
if (row) row.parentNode.removeChild(row);
}
// Previously shown helper
function upTo(el, tagName) {
tagName = tagName.toLowerCase();
while (el && el.parentNode) {
el = el.parentNode;
if (el.tagName && el.tagName.toLowerCase() == tagName) {
return el;
}
}
return null;
}
</script>

Categories

Resources