console.log gives out undefined on my input field - javascript

script:
$(document).ready(function (){
$(document).on('click', '.add_category', function(e){
e.preventDefault();
var data = {
'category_name': $('.category_name').val(),
'category_description': $('.category_description').val(),
}
console.log(data);
});
});
form:
<h4 class="text-center font-weight-bold">Add New Category</h4>
<div class="form-group">
<input type="text" class="form-control form-group w-100" placeholder="Category Name" class="category_name">
</div>
<div class="form-group">
<textarea class="form-control w-100" placeholder="Category Description" class="category_description" cols="50" rows="10"></textarea>
</div>
need advice, my input fields event with me adding content returns undefined even when the variable is the same at the input type and the script's var data
I also tried to change class="category_name" to name="category_name"
What am I missing?

Your HTML tags include two class attributes:
<input type="text" class="form-control form-group w-100" placeholder="Category Name" class="category_name">
^^^ here ^^^ and here
The browser is ignoring the second one, so your jQuery selectors are returning empty sets.
You should combine the class attributes into one string:
<input type="text" class="form-control form-group w-100 category_name" placeholder="Category Name">

You cannot double declare class.
Where you had <input type="text" class="form-control form-group w-100" placeholder="Category Name" class="category_name">
You instead need to declare all classes together, like so:
<input type="text" class="category_name form-control form-group w-100" placeholder="Category Name" >
document.getElementById('submit').onclick=function(e){
e.preventDefault();
var data = {
'category_name': document.getElementsByClassName('category_name')[0].value,
'category_description': document.getElementsByClassName('category_description')[0].value,
}
console.log(data);
};
<h4 class="text-center font-weight-bold">Add New Category</h4>
<div class="form-group">
<input type="text" class="form-control form-group w-100 category_name" placeholder="Category Name" value="">
</div>
<div class="form-group">
<textarea class="form-control w-100 category_description" placeholder="Category Description" cols="50" rows="10" value=""></textarea>
</div>
<button id="submit"> Save</button>

Related

Disable textbox inside an AngularJS Dynamic form

I need to disable the textbox inside my angularJS dynamic form after I clicked the button. my code seems to be working fine if I am going to disable textbox outside the dynamic form but when I get the ID of the textbox inside the dynamic form it is not working. What could be the problem.
$scope.copyText = function () {
document.getElementById('copyText').disabled=true;
document.getElementById('bName').disabled=true;
document.getElementById('pName').disabled=true;
// $('#bName').attr('disabled', true);
//alert('#bName');
$scope.LanguageFormData.language = [
{ bName: document.getElementById('brandName').value, pName: document.getElementById('prodName').value, pNameSub: document.getElementById('prodNameSub').value, lFeature: document.getElementById('pfeatureNew').value, lIngredient: document.getElementById('pingredientNew').value, lInstruction: document.getElementById('pinstructionNew').value, languageCat: null }
];
My View looks like this
<div class="col-md-12" class="pull-right" >
<button class="btn btn-primary pull-right" type="button" ng-click="copyText()" id="copyText" value="">COPY</button>
</div>
</div>
<div id="web" ng-repeat="languageItem in LanguageFormData.language">
<div class="row col-xs-12">
<div class="col-xs-6">
<br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Brand Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" ng-required="true" name="bName" id="bName" class="form-control" ng-model="languageItem.bName" required/>
</div>
</div><br/><br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Product Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" name="pName" ng-required="true" id="pName" ng-model="languageItem.pName" required/>
</div>
</div><br/><br/><br/>
Why not use ng-disabled. You need to change $scope.disableThis=false; back to false to re-enable the text somewhere else inside the controller code.
$scope.copyText = function () {
$scope.disableThis=true;
$scope.LanguageFormData.language = [
{ bName: document.getElementById('brandName').value, pName: document.getElementById('prodName').value, pNameSub: document.getElementById('prodNameSub').value, lFeature: document.getElementById('pfeatureNew').value, lIngredient: document.getElementById('pingredientNew').value, lInstruction: document.getElementById('pinstructionNew').value, languageCat: null }
];
Suggestions:
I have some doubts on the above code, you can just use the $scope.LanguageFormData.language as is, since you are using ng-model in the input fields, the data of the variable is updated dynamically, you can check this by {{LanguageFormData.language}} printing the output in the HTML
HTML:
<div class="col-md-12" class="pull-right" >
<button class="btn btn-primary pull-right" type="button" ng-click="copyText()" id="copyText" ng-disabled="disableThis" value="">COPY</button>
</div>
</div>
<div id="web" ng-repeat="languageItem in LanguageFormData.language">
<div class="row col-xs-12">
<div class="col-xs-6">
<br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Brand Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" ng-required="true" name="bName" id="bName" ng-disabled="disableThis" class="form-control" ng-model="languageItem.bName" required/>
</div>
</div><br/><br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Product Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" name="pName" ng-required="true" id="pName" ng-model="languageItem.pName" ng-disabled="disableThis" required/>
</div>
</div><br/><br/><br/>
Suggestions:
It would be good if you restrict the ID for one particular element alone, its a good practice to follow in general!

angular 2 template doesnt recognize template reference variables

I am working on building a site with Angular 2 and am having some problems with template reference variables. I am creating a pretty straightforward form to add a new listing to an online store:
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="productSKU">Product SKU</label>
<input #productSKU type="text" class="form-control" id="productSKU" placeholder="Enter Product SKU">
</div>
<div class="form-group">
<label for="productTitle">Product Title</label>
<input type="text" class="form-control" id="productTitle" placeholder="Enter Product Title" #productTitle>
</div>
<div class="form-group">
<label for="productSubtitle">Product Subtitle</label>
<input type="text" class="form-control" id="productSubtitle" placeholder="Enter Product Subtitle" #productSubtitle>
</div>
<div class="form-group">
<label for="productPrice">Product Price (USD)</label>
<input type="text" class="form-control" id="productPrice" placeholder="Enter Product Price" #productPrice>
</div>
<div class="form-group">
<label for="productType">Select Product Type</label>
<select multiple class="form-control" id="productType" #productType>
<option *ngFor="let type of listingTypes" [value]="type">{{type}}</option>
</select>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="productDescription">Product Description</label>
<textarea class="form-control" id="productDescription" rows="8" #productDescription></textarea>
</div>
<div class="form-group">
<label for="productCondition">Product Condition</label>
<input type="text" class="form-control" id="productCondition" placeholder="Enter Product Condition" #productCondition>
</div>
<div class="form-group">
<label for="storageLocation">Storage Location</label>
<input class="form-control" id="storageLocation" placeholder="Enter Storage Location" #storageLocation>
</div>
<div class="form-group">
<label for="image1Path">Image 1</label>
<input type="text" class="form-control" name="image1Path" id="image1Path" placeholder="Enter Image 1 File Name" #image1Path>
</div>
<button class="btn" id="newPostSubmitButton" (click)="onNewListingSubmit(productTitle.value,
productSubtitle.value,
productType.value,
productPrice.value,
productDescription.value,
productCondition.value,
productSKU.value,
storageLocation.value,
image1Path.value)">Submit</button>
</div>
For some reason when I try to trigger the onNewListingSubmit method in the component on the submit button click, it is giving me the following error:
As you can see, it can't find the property "value" of undefined. It seems to not be recognizing the various template reference variables throughout the form (e.g. #productSKU, #productPrice, etc.)
Any ideas why this might be happening? Can't seem to find any other examples of the same problem. Thanks
Looks like productCondition is not defined on template.
Since you use textarea element. There's no direct property value in textarea. At least its value defined for the collection of elements in textarea.

How to get datatype attribute in jquery?

Suppose that I've this <div>:
<div id="input-containers">
<div class="form-group" datatype="admins operators">
<label for="first-name"> *</label>
<input type="text" id="first-name" class="form-control required" />
</div>
<div class="form-group" datatype="admins operators">
<label for="last-name"></label>
<input type="text" id="last-name" class="form-control required" />
</div>
</div>
As you can see I've two <input>s, what I need to do is get all the <input> to have operators as datatype, I did this:
$('#input-containers :input').each(function()
{
console.log($(this).attr('datatype'));
});
but this returns undefined, why?
This will work:
$('#input-containers .form-group').each(function(){
console.log($(this).attr('datatype'));
});
Or if you want to use your code, you should place the datatype attribute on the input tag.
You should target the parent div having class name .form-group and get the attribute
check the below snippet
$(document).ready(function () {
$('#input-containers :input').each(function()
{
console.log($(this).parent('.form-group').attr('datatype'));
});
});
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<div id="input-containers">
<div class="form-group" datatype="admins operators">
<label for="first-name"> *</label>
<input type="text" id="first-name" class="form-control required" />
</div>
<div class="form-group" datatype="admins operators">
<label for="last-name"></label>
<input type="text" id="last-name" class="form-control required" />
</div>
</div>
You need to use .closest() to traverse up to parent div as this refers to input which doesn't the said attribute
$('#input-containers form-group[datatype] :input').each(function() {
console.log($(this).closest('.form-group').attr('datatype'));
});
$('#input-containers form-group[datatype] :input').each(function() {
console.log($(this).closest('.form-group').attr('datatype'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="input-containers">
<div class="form-group" datatype="admins operators">
<label for="first-name">*</label>
<input type="text" id="first-name" class="form-control required" />
</div>
<div class="form-group" datatype="admins operators">
<label for="last-name"></label>
<input type="text" id="last-name" class="form-control required" />
</div>
</div>
However I would recommend you to use data-* prefixed attribute
<div class="form-group" data-type="admins operators">
Then use
$('#input-containers form-group[datatype] :input').each(function() {
console.log($(this).closest('.form-group').attr('data-type'));
});
.data() can also be used. However it should be used judiciously.
Try this way it will also work,
JS:
$('#input-containers :input').each(function()
{
console.log(this.parentElement.getAttribute('datatype'));
});

Convert mutlidimensional inputs to JavaScript object

I've been trying to solve this one for several days now and it's driving me nuts. I have some data that needs to be submitted by Ajax. It is dynamic, so I don't know how many fields it has. On top of that the names of the fields are multidimensional and also dynamic. For example one might have inputs with the name data[name] and data[title] whilst another larger one might have data[images][0][src], data[images][0][alt], data[images][0][description], data[images][1][src], data[images][1][alt], data[images][1][description] with an unknown number of elements to the array. My problem is that I need to get an object I can submit via Ajax whilst maintaining the structure of the data.
I've tried serialising the data, but that just comes up with a string of name = value. I've tried serialise array as well, but that just gives me an array of [name, value]. I've managed to generate the object manually using a regex to split it up, but I can't find a way to merge the resultant objects together. The latest version of my code is:
$('.modal-content').find('input[name^="data"]').each(function () {
var found = $(this).attr('name').match(re).reverse();
var temp = $(this).val();
$.each(found, function ()
{
str = this.substr(1, this.length - 2);
var t = {};
t[str] = temp;
temp = t;
});
data = $.each({}, data, temp);
});
Unfortunately it doesn't merge them, it overwrites what is in data with what is in temp. If data has data.images[0].src = "mysrc" and temp has data.images[0].alt = "myalt" then I just end up with data.images[0].alt = "myalt" and src is no longer there.
There has to be a simple way to do this, hell at this point I'd even take a complicated way to do this. Can someone please help me with this?
Although there is already an accepted answer. Here are my 5 cents:
IMHO working with regex should be avoided when possible. So my suggestion would be to change the HTML a bit, adding some classes to the div that contain the image and change the name attribute of the inputs:
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div class="my-image">
<img src="http://localhost:8000/img/example.jpg">
<input type="hidden" name="src" value="img/example.jpg">
<div class="form-group">
<label for="title-0">Title:</label>
<input type="text" name="title" class="form-control" id="title-0" value="Default Example Image 1" placeholder="Title">
</div>
<div class="form-group">
<label for="description-0">Description:</label>
<input type="text" name="description" class="form-control" id="description-0" value="A default example image." placeholder="Description">
</div>
<div class="form-group">
<label for="alt-0">Alt tag (SEO):</label>
<input type="text" name="alt" class="form-control" id="alt-0" value="fluid gallery example image" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-0">Order:</label>
<input type="number" name="order" class="form-control image-order" id="order-0" value="0">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div class="my-image">
<img src="http://localhost:8000/img/example.jpg">
<input type="hidden" name="src" value="img/example.jpg">
<div class="form-group">
<label for="title-1">Title:</label>
<input type="text" name="title" class="form-control" id="title-1" value="Default Example Image 2" placeholder="Title">
</div>
<div class="form-group">
<label for="description-1">Description:</label>
<input type="text" name="description" class="form-control" id="description-1" value="A default example image." placeholder="Description">
</div>
<div class="form-group">
<label for="alt-1">Alt tag (SEO):</label>
<input type="text" name="alt" class="form-control" id="alt-1" value="fluid gallery example image" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-1">Order:</label>
<input type="number" name="order" class="form-control image-order" id="order-1" value="1">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
Then build the object matching this class:
var obj = {
data: {
images: []
}
}
var groups = $('.my-image');
groups.each(function(idx, el) {
var child = {}
$(el).find('input').each(function(jdx, info){
var $info = $(info);
child[$info.attr('name')] = $info.val();
});
obj.data.images.push(child);
});
We would have the same result, but it might be less error prone. Here is a plunker.
You can loop all inputs with each() loop, create array from name attributes using split() and then use reduce to add to object
var result = {}
$('input').each(function() {
var name = $(this).attr('name');
var val = $(this).val();
var ar = name.split(/\[(.*?)\]/gi).filter(e => e != '');
ar.reduce(function(a, b, i) {
return (i != (ar.length - 1)) ? a[b] || (a[b] = {}) : a[b] = val;
}, result)
})
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="gallery-images" class="ui-sortable">
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div>
<img src="http://localhost:8000/img/example.jpg">
<input type="hidden" name="data[images][0][src]" value="img/example.jpg">
<div class="form-group">
<label for="title-0">Title:</label>
<input type="text" name="data[images][0][title]" class="form-control" id="title-0" value="Default Example Image 1" placeholder="Title">
</div>
<div class="form-group">
<label for="description-0">Description:</label>
<input type="text" name="data[images][0][description]" class="form-control" id="description-0" value="A default example image." placeholder="Description">
</div>
<div class="form-group">
<label for="alt-0">Alt tag (SEO):</label>
<input type="text" name="data[images][0][alt]" class="form-control" id="alt-0" value="fluid gallery example image" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-0">Order:</label>
<input type="number" name="data[images][0][order]" class="form-control image-order" id="order-0" value="0">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div>
<img src="http://localhost:8000/img/example.jpg">
<input type="hidden" name="data[images][1][src]" value="img/example.jpg">
<div class="form-group">
<label for="title-1">Title:</label>
<input type="text" name="data[images][1][title]" class="form-control" id="title-1" value="Default Example Image 2" placeholder="Title">
</div>
<div class="form-group">
<label for="description-1">Description:</label>
<input type="text" name="data[images][1][description]" class="form-control" id="description-1" value="A default example image." placeholder="Description">
</div>
<div class="form-group">
<label for="alt-1">Alt tag (SEO):</label>
<input type="text" name="data[images][1][alt]" class="form-control" id="alt-1" value="fluid gallery example image" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-1">Order:</label>
<input type="number" name="data[images][1][order]" class="form-control image-order" id="order-1" value="1">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div>
<img src="http://localhost:8000/uploads/galleries\21\4-tux-30.jpg">
<input type="hidden" name="data[images][2][src]" value="uploads/galleries\21\4-tux-30.jpg">
<div class="form-group">
<label for="title-2">Title:</label>
<input type="text" name="data[images][2][title]" class="form-control" id="title-2" value="" placeholder="Title">
</div>
<div class="form-group">
<label for="description-2">Description:</label>
<input type="text" name="data[images][2][description]" class="form-control" id="description-2" value="" placeholder="Description">
</div>
<div class="form-group">
<label for="alt-2">Alt tag (SEO):</label>
<input type="text" name="data[images][2][alt]" class="form-control" id="alt-2" value="" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-2">Order:</label>
<input type="number" name="data[images][2][order]" class="form-control image-order" id="order-2" value="2">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
<li class="col-xs-12 col-sm-6 col-md-4 col-lg-3 gallery-image ui-sortable-handle">
<div>
<img src="http://localhost:8000/uploads/galleries\21\all-free-backgrounds-simple-style-darkblue-18.jpg">
<input type="hidden" name="data[images][3][src]" value="uploads/galleries\21\all-free-backgrounds-simple-style-darkblue-18.jpg">
<div class="form-group">
<label for="title-3">Title:</label>
<input type="text" name="data[images][3][title]" class="form-control" id="title-3" value="" placeholder="Title">
</div>
<div class="form-group">
<label for="description-3">Description:</label>
<input type="text" name="data[images][3][description]" class="form-control" id="description-3" value="" placeholder="Description">
</div>
<div class="form-group">
<label for="alt-3">Alt tag (SEO):</label>
<input type="text" name="data[images][3][alt]" class="form-control" id="alt-3" value="" placeholder="Alt tag">
</div>
<div class="form-group">
<label for="order-3">Order:</label>
<input type="number" name="data[images][3][order]" class="form-control image-order" id="order-3" value="3">
</div>
<button type="button" class="btn btn-danger remove-gallery-image-btn">× Delete</button>
</div>
</li>
</ul>

How do I get the value of a child on clicking another child of a parent Class?

consider I have such a structure(a group of fields which repeat);
<div class="form-group Row"> <!-- first row-->
<div class="col-sm-3">
<input type="text" class="form-control User" name="user" value="$users" placeholder="Username" />
</div>
<div class="col-sm-3">
<input type="password" class="form-control" name="pw" value="$passwords" placeholder="Password" />
</div>
<a class="delete" onclick='//do something'><img src="delete.png"></a>
</div>
<div class="form-group Row"><!-- second row-->
<div class="col-sm-3">
<input type="text" class="form-control User" name="user" value="$user" placeholder="Username" />
</div>
<div class="col-sm-3">
<input type="password" class="form-control" name="pw" value="$passwords" placeholder="Password" />
</div>
<a class="delete" onclick='//do something'><img src="delete.png"></a>
</div>
when I click on the delete-image of any Row, I want to get the value of the input field with class name "User" of this specific Row.
How can I do this in javascript?
If you use jQuery you don't need use inline events, you can add events with .on function, and get value like in example
$('.delete').on('click', function () {
var value = $(this).parent().find('.User').val();
console.log(value)
});
Example
Try as follows:
$('.delete').on('click', function(){
var value = $(this).closest('.row').find('.User').val();
//Do something with value;
});
In vanilla JS your "do something" will be like this:
alert( this.parentNode.getElementsByClassName("user")[0].value; )

Categories

Resources