Change part of an attribute after cloning with jQuery - html

I have a table with different inputs. Using a button, I want to clone the last row of the table, and add it to the table. Furthermore, I want to replace the "index" in the name with the variable of the index.
How can I replace the string "index" with the variable index?
In this example I just show one input, because it is sufficient to get a clue.
<table class='taskTable'>
<tr>
<td>
<input name='data[index][description]'></input>
<input name='data[index][text]'></input>
<input name='data[index][date]'></input>
</td>
</tr>
</table>
<button type='button' class='addTask'>Add Row</button>
<script>
var index = 1;
$(".addTask").on('click', function(){
index = index+1;
var lastTr = $('.taskTable').find('tr:last').clone();
//replace now the string index of the name with the variable
$('.taskTable').append(lastTr);
});
</script>
Here is a link to the jsFiddle
https://jsfiddle.net/tg53c96m/

Set the name with .attr("name", value):
var newName = `data[${index}][description]`;
lastTr.find("input").attr("name", newName);
Or if you want to search/replace:
lastTr.find("input").attr("name",
(i, oldName) => oldName.replace(/\[.*\]\[/, `[${index}][`));
var index = 1;
$(".addTask").on('click', function() {
index = index + 1;
var lastTr = $('.taskTable').find('tr:last').clone();
lastTr.find("input").attr("name",
(i, oldName) => oldName.replace(/\[.*\]\[.*\]$/, `[${index}][description]`));
console.log("New name: ", lastTr.find("input").attr("name"));
$('.taskTable').append(lastTr);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class='taskTable'>
<tr>
<td>
<input name='data[index][description]'>
</td>
</tr>
</table>
<button class='addTask'>Add Row</button>

Update
Just saw the edited HTML so here's the added function to handle multiple inputs with different names:
lastTr.find('input').each(function() {
let nameText = $(this).attr('name');
let newName = nameText.split('index').join(rows);
$(this).attr('name', newName);
});
In order to change the pattern of each name without having to remember which one is which is to handle only the portion of the names that actually changes:
let newName = nameText.split('index').join(rows);
nameText is the current input name which is s String value of either:
'data[index][description]',
'data[index][text]',
/* OR */
'data[index][date]'
When .split() into an Array of Strings, it removes the text: "index":
nameText.split('index')
// Returns ['data[', '][`description or text or date`]']
Finally .join() will convert the Array of Strings into a String with the variable index number between them:
.join(index)
// Returns `'data['+index+'][`description or text or date`]'`
Add the following statement as the first line of the function:
let rows = $('.taskTable tr').length;
This will be the number of rows already in the table.
Add this after the row has been cloned but before it is appended:
lastTr.find('input').attr('name', 'data' + rows);
This finds the input nested within the new row and assign it name="data'+rows. I'm not sure what's with the [description] part of the name. Is it dynamic or literal like the [index] part. It sounds like something isn't quite right about those names...
Note: The rest of the name can be whatever, I just feel wrong to have a name looking like that. The contacted string will look like the following with the original text:
lastTr.find('input').attr('name', 'data[' + rows + '][description]');
Also, I added another function that will change all row input with the new naming pattern.
Demo
/*
This will change all row input names from
'data[index][description]'
'data[index][text]'
'data[index][date]'
to
'data['+index+'][description]'
'data['+index+'][text]'
'data['+index+'][date]'
index = 0,...N
*/
$('.addTask tr').each(function(index) {
$(this).find('input').each(function() {
let nameText = $(this).attr('name');
let newName = nameText.split('index').join(index);
$(this).attr('name', newName);
});
});
$(".addTask").on('click', function(index) {
let rows = $('.taskTable tr').length;
const lastTr = $('.taskTable').find('tr:last').clone();
lastTr.find('input').each(function() {
let nameText = $(this).attr('name');
let newName = nameText.split('index').join(rows);
$(this).attr('name', newName);
});
$('.taskTable').append(lastTr);
});
<table class='taskTable'>
<tr><td>
<input name='data[index][description]'>
<input name='data[index][text]'>
<input name='data[index][date]'>
</td></tr>
<tr><td>
<input name='data[index][description]'>
<input name='data[index][text]'>
<input name='data[index][date]'>
</td></tr>
</table>
<button class='addTask' type='button'>Add Row</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

While user enters a value separated by comma in an input fields. The how to display the out put in list format

Here in this input fields. While user enters a value which is separated by a comma. For example like "apple,Banana,grapes,mango". So here if user enters the value in this format. Then I want to display the output in list format like
apple
Banana
grapes
mango
So if it can be done please let know how to do this. Below is my code where I have tried
<input type='text' id='idea' />
<input type='button' value='add to list' id='add' />
<ul id='list'></ul>
<script>
document.getElementById("add").onclick = function() {
//First things first, we need our text:
var text = document.getElementById("idea").value; //.value gets input values
//Now construct a quick list element
var li = "<li>" + text + "</li>";
//Now use appendChild and add it to the list!
document.getElementById("list").appendChild(li);
}
</script>
You were almost there, but you can not append HTML in strings, you need to create proper list item objects and append those:
document.getElementById("add").onclick = function() {
// cache the list
const list = document.getElementById("list");
//First things first, we need our text:
const items = document.getElementById("idea").value.split(','); //.value gets input values, .split(',') makes it an array of values
// foreach entry in the text array, create and append an li
for (const item of items) {
const li = document.createElement('li');
li.textContent = item;
list.appendChild(li);
}
}
<input type='text' id='idea' />
<input type='button' value='add to list' id='add' />
<ul id='list'></ul>

Get a number from HTML text when it contains a comma

I have a comma-separated number in my table. But my js on click gives only the values before the comma instead of the whole number.
<td class="amt">1,000,000.50</td>
Below is my jQuery that alerts 1.00 instead of the whole value:
$(".amt").click(function(){
var t = parseFloat($(this).text()).toFixed(2);
alert(t);
})
This code alerts the exact figure but how can I get it as a number?
$(".amt").click(function(){
var t = $(this).text();
alert(t);
})
You can use regex to remove comma and parseFloat as
parseFloat($(this).text().replace(/,/g,'')
$(".amt").click(function(){
var t = parseFloat($(this).text().replace(/,/g,''));
alert(t)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td class="amt">1,000,000.50</td>
</tr>
</table>
You are close, but before you try to convert the number string into a float using parseFloat, first you must remove all the commas from the string. You can do that using
textString.replace(/,/g, '');
Working Example:
$(".amt").click(function(){
var textString = $(this).text();
var numString = textString.replace(/,/g, '');
var numAsFloat = parseFloat(numString ).toFixed(2);
console.log("Float value = "+numAsFloat);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="amt">1,000,000.50</div>

Get the radio button value in a form [duplicate]

I’m having some strange problem with my JS program. I had this working properly but for some reason it’s no longer working. I just want to find the value of the radio button (which one is selected) and return it to a variable. For some reason it keeps returning undefined.
Here is my code:
function findSelection(field) {
var test = 'document.theForm.' + field;
var sizes = test;
alert(sizes);
for (i=0; i < sizes.length; i++) {
if (sizes[i].checked==true) {
alert(sizes[i].value + ' you got a value');
return sizes[i].value;
}
}
}
submitForm:
function submitForm() {
var genderS = findSelection("genderS");
alert(genderS);
}
HTML:
<form action="#n" name="theForm">
<label for="gender">Gender: </label>
<input type="radio" name="genderS" value="1" checked> Male
<input type="radio" name="genderS" value="0" > Female<br><br>
Search
</form>
This works with any explorer.
document.querySelector('input[name="genderS"]:checked').value;
This is a simple way to get the value of any input type.
You also do not need to include jQuery path.
You can do something like this:
var radios = document.getElementsByName('genderS');
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
// do whatever you want with the checked radio
alert(radios[i].value);
// only one radio can be logically checked, don't check the rest
break;
}
}
<label for="gender">Gender: </label>
<input type="radio" name="genderS" value="1" checked="checked">Male</input>
<input type="radio" name="genderS" value="0">Female</input>
jsfiddle
Edit: Thanks HATCHA and jpsetung for your edit suggestions.
document.forms.your-form-name.elements.radio-button-name.value
Since jQuery 1.8, the correct syntax for the query is
$('input[name="genderS"]:checked').val();
Not $('input[#name="genderS"]:checked').val(); anymore, which was working in jQuery 1.7 (with the #).
ECMAScript 6 version
let genderS = Array.from(document.getElementsByName("genderS")).find(r => r.checked).value;
Here's a nice way to get the checked radio button's value with plain JavaScript:
const form = document.forms.demo;
const checked = form.querySelector('input[name=characters]:checked');
// log out the value from the :checked radio
console.log(checked.value);
Source: https://ultimatecourses.com/blog/get-value-checked-radio-buttons
Using this HTML:
<form name="demo">
<label>
Mario
<input type="radio" value="mario" name="characters" checked>
</label>
<label>
Luigi
<input type="radio" value="luigi" name="characters">
</label>
<label>
Toad
<input type="radio" value="toad" name="characters">
</label>
</form>
You could also use Array Find the checked property to find the checked item:
Array.from(form.elements.characters).find(radio => radio.checked);
In case someone was looking for an answer and landed here like me, from Chrome 34 and Firefox 33 you can do the following:
var form = document.theForm;
var radios = form.elements['genderS'];
alert(radios.value);
or simpler:
alert(document.theForm.genderS.value);
refrence: https://developer.mozilla.org/en-US/docs/Web/API/RadioNodeList/value
Edit:
As said by Chips_100 you should use :
var sizes = document.theForm[field];
directly without using the test variable.
Old answer:
Shouldn't you eval like this ?
var sizes = eval(test);
I don't know how that works, but to me you're only copying a string.
Try this
function findSelection(field) {
var test = document.getElementsByName(field);
var sizes = test.length;
alert(sizes);
for (i=0; i < sizes; i++) {
if (test[i].checked==true) {
alert(test[i].value + ' you got a value');
return test[i].value;
}
}
}
function submitForm() {
var genderS = findSelection("genderS");
alert(genderS);
return false;
}
A fiddle here.
This is pure JavaScript, based on the answer by #Fontas but with safety code to return an empty string (and avoid a TypeError) if there isn't a selected radio button:
var genderSRadio = document.querySelector("input[name=genderS]:checked");
var genderSValue = genderSRadio ? genderSRadio.value : "";
The code breaks down like this:
Line 1: get a reference to the control that (a) is an <input> type, (b) has a name attribute of genderS, and (c) is checked.
Line 2: If there is such a control, return its value. If there isn't, return an empty string. The genderSRadio variable is truthy if Line 1 finds the control and null/falsey if it doesn't.
For JQuery, use #jbabey's answer, and note that if there isn't a selected radio button it will return undefined.
First, shoutout to ashraf aaref, who's answer I would like to expand a little.
As MDN Web Docs suggest, using RadioNodeList is the preferred way to go:
// Get the form
const form = document.forms[0];
// Get the form's radio buttons
const radios = form.elements['color'];
// You can also easily get the selected value
console.log(radios.value);
// Set the "red" option as the value, i.e. select it
radios.value = 'red';
One might however also select the form via querySelector, which works fine too:
const form = document.querySelector('form[name="somename"]')
However, selecting the radios directly will not work, because it returns a simple NodeList.
document.querySelectorAll('input[name="color"]')
// Returns: NodeList [ input, input ]
While selecting the form first returns a RadioNodeList
document.forms[0].elements['color']
// document.forms[0].color # Shortcut variant
// document.forms[0].elements['complex[naming]'] # Note: shortcuts do not work well with complex field names, thus `elements` for a more programmatic aproach
// Returns: RadioNodeList { 0: input, 1: input, value: "red", length: 2 }
This is why you have to select the form first and then call the elements Method. Aside from all the input Nodes, the RadioNodeList also includes a property value, which enables this simple manipulation.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/RadioNodeList/value
Here is an Example for Radios where no Checked="checked" attribute is used
function test() {
var radios = document.getElementsByName("radiotest");
var found = 1;
for (var i = 0; i < radios.length; i++) {
if (radios[i].checked) {
alert(radios[i].value);
found = 0;
break;
}
}
if(found == 1)
{
alert("Please Select Radio");
}
}
DEMO : http://jsfiddle.net/ipsjolly/hgdWp/2/ [Click Find without selecting any Radio]
Source (from my blog): http://bloggerplugnplay.blogspot.in/2013/01/validateget-checked-radio-value-in.html
Putting Ed Gibbs' answer into a general function:
function findSelection(rad_name) {
const rad_val = document.querySelector('input[name=' + rad_name + ']:checked');
return (rad_val ? rad_val.value : "");
}
Then you can do findSelection("genderS");
lets suppose you need to place different rows of radio buttons in a form, each with separate attribute names ('option1','option2' etc) but the same class name. Perhaps you need them in multiple rows where they will each submit a value based on a scale of 1 to 5 pertaining to a question. you can write your javascript like so:
<script type="text/javascript">
var ratings = document.getElementsByClassName('ratings'); // we access all our radio buttons elements by class name
var radios="";
var i;
for(i=0;i<ratings.length;i++){
ratings[i].onclick=function(){
var result = 0;
radios = document.querySelectorAll("input[class=ratings]:checked");
for(j=0;j<radios.length;j++){
result = result + + radios[j].value;
}
console.log(result);
document.getElementById('overall-average-rating').innerHTML = result; // this row displays your total rating
}
}
</script>
I would also insert the final output into a hidden form element to be submitted together with the form.
I realize this is extremely old, but it can now be done in a single line
function findSelection(name) {
return document.querySelector(`[name="${name}"]:checked`).value
}
I prefer to use a formdata object as it represents the value that should be send if the form was submitted.
Note that it shows a snapshot of the form values. If you change the value, you need to recreate the FormData object. If you want to see the state change of the radio, you need to subscribe to the change event change event demo
Demo:
let formData = new FormData(document.querySelector("form"));
console.log(`The value is: ${formData.get("choice")}`);
<form>
<p>Pizza crust:</p>
<p>
<input type="radio" name="choice" value="regular" >
<label for="choice1id">Regular crust</label>
</p>
<p>
<input type="radio" name="choice" value="deep" checked >
<label for="choice2id">Deep dish</label>
</p>
</form>
If it is possible for you to assign a Id for your form element(), this way can be considered as a safe alternative way (specially when radio group element name is not unique in document):
function findSelection(field) {
var formInputElements = document.getElementById("yourFormId").getElementsByTagName("input");
alert(formInputElements);
for (i=0; i < formInputElements.length; i++) {
if ((formInputElements[i].type == "radio") && (formInputElements[i].name == field) && (formInputElements[i].checked)) {
alert(formInputElements[i].value + ' you got a value');
return formInputElements[i].value;
}
}
}
HTML:
<form action="#n" name="theForm" id="yourFormId">
I like to use brackets to get value from input, its way more clear than using dots.
document.forms['form_name']['input_name'].value;
var value = $('input:radio[name="radiogroupname"]:checked').val();

Angular search in a table

I want to make a search on the column SN in a table.
there many information in my table, I want to be able to search based on SN but when I add the filter it does not even load my table
This is what I did:
in My controler my List is filled :
$scope.List = {};
MyServices.getList()
.success(function (data) {
angular.forEach(data, function (value, index) {
$scope.List[value.SN] = {
Description: value.Description,
SN: value.SN
}
});
})
.error(function (error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
and this is my HTML:
<label>Search: <input ng-model="search.SN"></label>
<tr ng-repeat="V in List| filter:search">
<td>{{V.SN}}</td>
<td>{{V.Description}}</td>
</tr>
You must write as follow:
<label>Search: <input ng-model="search.SN"></label>
<tr ng-repeat="V in List| filter: {SN: search.SN}">
<td>{{V.SN}}</td>
<td>{{V.Description}}</td>
</tr>
Remove the object declaration on the input field. It will match the whole object for your specified value on the input field:
<label>Search: <input ng-model="search"></label>
<tr ng-repeat="V in List| filter: search">
<td>{{V.SN}}</td>
<td>{{V.Description}}</td>
</tr>

Using angularjs, how to perform math operations on textboxes and see result as the values are being typed in?

I have an HTML file with 2 textboxes, one for value and the other for quantity. The result text at the bottom multiplies value with quantity and show the result.
The intention is to show the sum of all the rows of pairs of textboxes on the screen. To that end, I have an "add new" button which keeps adding additional pairs of textboxes.
The first set of textboxes that appear on the HTML, reflect the size of the "numbers" array of objects containing properties "val" and "qty". The same values are bound to the textboxes.
However, only the first set of values are added on screen. As I keep adding new textboxes and entering new values, the value of the result should change accordingly, but it simply doesn't.
HTML Code
<div ng-app="adder" ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-model="number.val"></td>
<td><input type="text" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>pp',[]);
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{sum}}
</div>
</body>
</html>
Javascript
var myapp = angular.module('adder', []);
myapp.controller('addcontrol',function($scope){
$scope.numbers = [
{val:100,
qty:200,
}
];
$scope.add = function()
{
$scope.numbers.push({val:0,qty:0});
};
$scope.deleteNumber = function(val)
{
numbers.splice(val, 1);
};
var result=0;
angular.forEach($scope.numbers, function(num){
result+=(num.val * num.qty);
});
$scope.sum = result;
});
What am I doing wrong here?
In your code, the calculation of the sum would only be executed once.
You need to add a watch of the scope or bind a function to ng-change event in order to keep the sum updated while you change the numbers.
For example, you can do:
<div ng-app="adder" ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-change="update()" ng-model="number.val"></td>
<td><input type="text" ng-change="update()" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>pp',[]);
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{sum}}
</div>
And:
var myapp = angular.module('adder', []);
myapp.controller('addcontrol', function($scope) {
$scope.numbers = [{
val: 100,
qty: 200,
}
];
$scope.add = function() {
$scope.numbers.push({
val: 0,
qty: 0
});
};
$scope.deleteNumber = function(val) {
numbers.splice(val, 1);
$scope.update();
};
$scope.update = function() {
var result = 0;
angular.forEach($scope.numbers, function(num) {
result += (num.val * num.qty);
});
$scope.sum = result;
};
});
I know this a little bit besides the question but you can do arbitrary arithmetic operations inside a single input field:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="">
<input ng-model="expression"/>
<p>{{$eval(expression)}}</p>
</body>
Based on Pylinux's answer: it may seem obvious, however here it is. If you want to add 2 expressions, use the following:
{{$eval(expression1)+ $eval(expression2) }}
The code in your controller is only activated once (when the view is rendered). Therefore, your sum is only computed once, before you even get a chance to add any rows. What you need to do is put your calculation into a function so that it can be called repeatedly as needed.
Tong's answer is basically correct, but I think this is a nicer way to do it:
<div ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-model="number.val"></td>
<td><input type="text" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{total()}}
</div>
and
var app = angular.module('app', [])
.controller('addcontrol', function($scope) {
$scope.numbers = [{
val: 100,
qty: 200,
}];
$scope.add = function() {
$scope.numbers.push({
val: 0,
qty: 0
});
};
$scope.deleteNumber = function(val) {
$scope.numbers.splice(val, 1);
};
$scope.total = function(){
var total = 0;
angular.forEach($scope.numbers, function(num) {
total += (num.val * num.qty);
});
return total;
}
})
Define a total function that loops through the array and returns the appropriate sum. Then you can bind that function to the result field in the view. The benefit of doing it this way is that you don't have to remember to call update() everywhere that might cause the total to change (like ng-change on the textboxes, and in the deleteNumber function). The total just updates automatically.
Here's a demo.
Php
Create a database named as students(using cmd)
Create a table named as tbl_students_info with column:
id, data type is int with size of 11, auto increment and set as primary key
Firstname, data type is varchar with size of 30
Middlename, data type is varchar with size of 30
Lastname, data type is varchar with size of 30
Contact, data type is int with size of 11
House_address, data type is int with size of 50
Create a webpage that contains 5 textbox and 1 button. 1st textbox is for firstname, 2nd textbox is for middlename, 3rd textbox is for lastname, 4th textbox is for contact, last textbox is for house_address and button for saving the input data in those texboxes to database
Angular
Create a calculator that computes the sum of 2 numbers, product of 2 numbers, difference of 2 numbers and quotient of 2 numbers. The web page must contain 2 textbox and 4 buttons for the operations.
Create a wepage that computes the area of a triangle. Must have 2 textbox and a button for calculate area.
Create a website that calculate the age of the user. Must have a textbox and a button, textbox is for input birth year and button for compute age. Note: no need for exact months.
Help TT