Javascript Dynamic Form Field - javascript

I am having difficulty with a javascript that I need some help with. I have a form which sends to a php the exact amount of inputs to be filled, now I want to create a preview using jQuery/javascript but how can I catch all the fields dynamically.
Here is a portion of my form for reference:
<td>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-pencil"></i></span>
<input class="form-control" id="task" type="text" name="task" placeholder="Task Title">
</div>
</td>
<td>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-pencil"></i>
</span>
<input class="form-control" id="description" type="text" name="description" placeholder="Task Description">
</div>
</td>
So, I added in PHP the name field + the number, this way I can get different names ie: task1, task2,...etc.
Now what I need to do is get the values using jQuery/javascript.
My thoughts so far is to declare the var (variable) inside a for() (loop)
var task = $('input[name=task]').val();
How can I get all values task1, task2. No one knows how many task fields the user will submit so I need to get the number of fields
Any help direction so I can figure this out

First of all, you don't need to give your input fields names like task1, task2, etc to distinguish among them on the server-side i.e on the PHP. You just need to give all of them a name attribute value like tasks[] And notice the brackets [] so you may have something like the following:
<input class="form-control" id="tasks[]" type="text" name="tasks[]" placeholder="Task Title">
...
<input class="form-control" id="tasks[]" type="text" name="tasks[]" placeholder="Task Title">
Like that automatically values in those fields will be posted as an array to the PHP and it is going to be received like the following in PHP script:
$tasks = $_POST['tasks'];
foreach ($tasks as $task){
echo $task;
}
Second By this way you will easily able to collect your inputs data using Javascript inorder to generate the preview by using getElementsByName method as follows:
function preview(){
output = "";
tasks = document.getElementsByName('tasks[]');
for (i=0; i < tasks.length; i++){
output += "<b>Title</b>: "+tasks[i].value+"<hr />";
}
panel = document.getElementById('panel');
panel.innerHTML = output;
}
Of course you can expand this solution to any number of fields in your form such as descriptions[].
A javascript DEMO: http://jsbin.com/kiyisi/1/

Using the Attribute Starts With Selector [name^="value"] and jQuery.each()
var tasks = $('input[name^=task]').val();
$.each(tasks,function(index, value){
//do something with the value
alert($(this).val());
});
edit
var tasks = $('input[name^=task]');
$.each(tasks,function(index, value){
//do something with the value
$('#Preview').append($(this).val());
});

Q: now I want to create a preview using jquery/javascript but how can I catch all the fields dinamically:
If you give them a class, you can get all fields with each:
$(".className").each(function() {
do something
Next, "catch" all fields... I'm assuming you may want the values of these fields too? Check this example for details, here is a snippet which loads the key:value pairs (form field name : value of field) into a map:
var map = {};
$(".activeInput").each(function() {
map[$(this).attr("name")] = $(this).val();
});
Print all values inside div (Here, I'm assuming you're talking about children values of div):
<div>
<span>Hi</span>
<span>Hello</span>
<span>Hi again</span>
</div>
$("div").children().each(function () {
console.log($(this).text());
});
OR
$("div span").each(function () {
console.log($(this).text());
});

Related

Why isn't a single form element is not returning value in the controller?

In my Form 3 fields including a hidden.and the rest of the values are perfectly returns in controller ,But the value in the hidden field is not getting .
the value in the hidden field is passing from an anchor tag using java script.
The value for the hidden field is passing from here
<a href="#" onclick="func(#c.vid)" data-toggle="modal" data-target="#myModal3" class="modalLink">
Javascript code to pass the value is
function func(vd){
document.getElementsByClassName("hiddenid").value = vd;
}
Form is look like
<form action="/Home/AddToCart" method="post">
<input type="hidden" id="vid" name="vid" class="hiddenid" />
<div class="styled-input agile-styled-input-top">
<input type="text" placeholder="Name" name="name" id="name"required>
</div>
<div class="styled-input">
<input type="text" placeholder="Star Name" onclick="showsss()" name="star" id="star" required>
</div>
<input type="submit" value="Add To Cart">
</form>
Controller
[HttpPost]
public ActionResult AddToCart(cart data)
{
userService.AddToCart(data);
ViewBag.p = userService;
return RedirectToAction("Temple");
}
The value is passing to the hidden field perfectly.i checked using an alert box.am attaching a screen shot of what am getting in the controller.
getElementsByClassName return an array.
function func(vd){
document.getElementsByClassName("hiddenid")[0].value = vd;
}
getElementsByClassName returns an array. Access single element using array index.
document.getElementsByClassName("hiddenid")[0].value = vd;
Instead of className you can use id as it is present on your hidden field i:e vid.
document.getElementsById("vid").value = vd;
or you can use document.querySelector which will retrieve first match element.
document.querySelector('.hiddenid').value = vd;
or
document.querySelector('#vid').value = vd;
Since you are using byclass its return an array. try this
document.getElementsByClassName("hiddenid")[0].value = vd;
But if you have a multiple products then do you have a add to cart button better to used id like vid-unique_number

Need help converting jQuery function to JavaScript?

I am updating a product, I am able to have the product info prefill the update form and update the product info using jQuery but I want to use JavaScript. How do I convert this jQuery code to JavaScript?
I am following a tutorial online and the person is using jQuery which is cool but I want to see how to do the same method using Javascript.
Javascript Code:
$(document).on('pagebeforeshow', '#updatedialog', function() {
$('#newName').val(currentProduct.name);
$('#newQuantity').val(currentProduct.quantity);
});
function updateProduct() {
var newName = $('#newName').val();
var newQuantity = $('#newQuantity').val();
productHandler.updateProduct(currentProduct.id, newName, newQuantity);
}
HTML update form
<form>
<div class="ui-field-contain">
<label for="newName"
class="ui-hidden- accessible">Name</label>
<input type="text"
id="newName"
data-clear-btn="true"
placeholder="New Name"/>
<br/>
<label for="newQuantity"
class="ui-hidden-accessible">Quantity</label>
<input type="number"
name="number"
pattern="[0-9}"
id="newQuantity"
value=""
data-clear-btn="true"
placeholder="New Quantity"/>
<br/>
<button class="ui-btn ui-icon-plus ui-btn-icon-left"
id="btnupdate"
onclick="updateProduct()">
Update
</button>
</div>
</form>
The update form should populate with the information from the product that was already entered and then it should update the changes made to the fields and save it as a new object. I can do it in jQuery but I want help with doing it in Javascript.
Seems all you're currently doing with jquery is getting the value of input elements by their ID. You can do this with javascript by selecting the form element by ID and getting the value property.
val value = document.getElementById("elemID").value;
Your code should look like this
function updateProduct(){
var newName= document.getElementById("newName").value;
var newQuantity = document.getElementById("newQuantity").value;
productHandler.updateProduct(currentProduct.id, newName, newQuantity);
}
you can get values of of the element by id using document try the following
function updateProduct(){
var newName=document.getElementById("newName").value;
var newQuantity=document.getElementById("newQuantity ").value;
productHandler.updateProduct(currentProduct.id, newName, newQuantity);
}

ng-repeat model binding (for adding dymaic created emails)

Below code show binding for a List emails but I am having trouble binding the newly added emails to the $scope.emails (does not contain the new email user added). Any idea?
// emails is a List on server side
// email is a string
so i bind ng-model= email but
but doing the below does not work
$scope.contactInformation.Emails.push(email); --> complains about duplicates
<div ng-repeat="email in emails">
<div class="form-group">
<label for="email">Email</label>
<div class="input-group input-group-sm input-group-minimal">
<span class="input-group-addon">
<i class="linecons-mail"></i>
</span>
<input type="text" class="form-control" ng-model="email" />
</div>
<button class="btn btn-primary" ng-show="$last" ng-click="AddEmail()">Add Email</button>
Controller.js
// modelParams.ContactInformation.Emails = new List(string)() when retrieved on server side
$scope.emails = modelParams.ContactInformation.Emails;
$scope.AddEmail = function () {
$scope.contactInformation.Emails.push({ email: null });
};
I'm amending the answer to avoid confusion... Here's is how it should be done - fill in the blanks to fit it for your scenario.
controller.js
// assuming emails is an array of strings (whether defined locally or from a server)
$scope.emails = ["email1", "email2", ...];
$scope.addEmail = function(){
$scope.emails.push(""); // push an empty array as new not-yet-set email
}
The HTML is largely correct. I would have moved the "add" button to outside of the ng-repeat div instead of relying on $last:
<div ng-repeat="email in emails track by $index">
<input type="text" ng-model="email" />
</div>
<button ng-click="addEmail()">Add Email</button>
EDIT:
The example above would, actually, not work because the ng-model within ng-repeat binds to a primitive (string) email.
There are 2 ways to fix:
approach 1
Make an array of objects. If you get an array of strings from the server, you'd need to convert to an array of objects, like so:
$scope.emails = [];
angular.forEach(arrayOfEmailStrings, function(v, k){ $scope.emails.push({value: v}); });
And access like so:
<input type="text" ng-model="email.value" />
approach 2
Use the $index property:
<input type="text" ng-model="emails[$index]" />

How do I replace part of the value of attributes for a set of elements in jQuery?

I am trying to replace a series of 'for' attributes of labels based on their current contents.
The application is using AJAX to add an item to an invoice without refreshing the page. Upon receiving notification of a successful item add, my script should replace all the labels in the form whose 'for' attribute ends with '-new' with the same attribute minus the '-new' and adding ('-' + itemValue), where itemValue is the item Id of the invoice item that was added.
I know how to select all the labels I want to change at once:
jQuery('label[for$=new]')
I know how to get their 'for' attribute:
jQuery('label[for$=new]').attr('for')
I tried the JavaScript replace method:
jQuery('label[for$=new]').attr('for').replace(/-new/,itemValue)
But that appears to select each label's 'for' attribute, replace the text, and pass the replaced text back (to nothing), since I don't know how to identify the labels that have the 'for' attribute I want to replace.
Here's some sample HTML:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF'];?>" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div id="InvoiceItem-new-1" class="InvoiceItem">
<label for="InvoiceItemNumber-new">New Invoice Item Number: </label>
<input id="InvoiceItemNumber-new" class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber-new">
<label for="InvoiceItemDescription-new">Item Description: </label>
<input id="InvoiceItemDescription-new" class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new">
<label for="InvoiceItemAmount-new">Item Amount: </label>
<input id="InvoiceItemAmount-new" class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new">
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
Once I get this to work, I'm going to replace all the ids for all the inputs. Same problem. I imagine the solution looks something like this:
jQuery('input[id$=new]').attr('id').replace(/-new/,itemValue)
I just cannot figure out the syntax for this at all.
No need to use .each() ... the .attr() method accepts a function as the second parameter that returns the new value to be used as replacement
jQuery('label[for$=new]').attr('for', function(index, currentValue){
return currentValue.replace(/-new/,'-' + itemValue);
});
If I may, why not just put the input tag inside the label tag? That way, you won't need a for attribute inside the label tag.
Next, a better way to accomplish what you're trying to do would be to use the invoice ID number as the ID for the surrounding div, and add a 'new` class for "new" invoice entries.
So your form would look something like this:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF']" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div class="InvoiceItem new">
<label>New Invoice Item Number: <input class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber"></label>
<label>Item Description: <input class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new"></label>
<label for="InvoiceItemAmount-new">Item Amount: <input class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new"></label>
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
You'll still have all the targetability you need to get the new invoice item field data, but now, you only have two things to do to convert from a "new" invoice row to an "existing" invoice item row: add an id attribute to the div and remove the new class, both of which jQuery will let you do quite easily.
Not sure I get the question, but something like:
var oldFor = $('label[for$=new]').attr('for');
var newFor = oldfor.replace(/-new/,itemValue);
$('label[for$=new]').attr('for', newFor);
.attr( attributeName, value )
attributeName = The name of the attribute to set.
value = A value to set for the attribute.
When selecting multiple elements, you will need to iterate:
$('label[for$=new]').each(function(index) {
$(this).attr('for', $(this).attr('for').replace(/-new/, '-' + itemValue));
});

Adding "i" to input field, but should be hidden

I want to add "i" to a input field when the red div is clicked, but the "i" that is added to the input field should not be viewable. If the green button is clicked the hidden "i" should be removed.
Here is my HTML live: http://jsfiddle.net/mtYtW/60/
My HTML:
<div class="input string optional">
<label for="company_navn" class="string optional">Name</label>
<input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:green;">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:red;">
</div>
How to create this functionality?
If you would like to associate data with a specific element, I suggest the .data() method of jQuery. Take a look at the jQuery docs. It's a much cleaner way of accomplishing your goal.
Here's a working Fiddle to get you started.
EDIT
Per the new requirement spelled out in the comments to your question, you can attach to the form submit event like this:
$('#yourForm').submit(function() {
if($('#webhost_navn').data('myData') == 'i')
{
var val = $('#webhost_navn').val();
$('#webhost_navn').val('i' + val);
}
});
NOTE: This code relys on the orginal code in my Fiddle.
It sounds like you want to associate some data with the input field, but not alter the input field's value. For that, you can use the data method:
$(document).ready(function() {
$('#redDiv').click(function() {
$('#webhost_navn').data('myData', 'i');
});
$('#greenDiv').click(function() {
$('#webhost_navn').data('myData', null);
});
});
You'll need to add id's to the red and green divs for the above example to work as is, respectively, redDiv and greenDiv. To retrieve the data you associate with the input, do this:
var myData = $('#webhost_navn').data('myData'); // Will equal 'i' or null
API Ref: http://api.jquery.com/data
EDIT: To append the "i" value to the input's value:
var myData = $('#webhost_navn').data('myData'),
val = $('#webhost_navn').val();
if (myData) {
$('#webhost_navn').val(myData + val);
}
Working example: http://jsfiddle.net/FishBasketGordo/e3yKu/
My update to your code here: http://jsfiddle.net/mtYtW/61/
Basically I gave your red/green button's id's and created a click event to add/remove the content. I also created a css definition for the color of the input box to be white so you don't see the text.
<div class="input string optional"><label for="company_navn" class="string optional"> Name</label><input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional"></div>
<div id='green' style="width:30px;height:30px;margin-top:10px;display:block;background:green;"></div>
<div id='red' style="width:30px;height:30px;margin-top:10px;display:block;background:red;"></div>
css:
label {display:block;}
#webhost_navn{color:white};
js:
$("#red").live("click",function()
{
$("#webhost_navn").val("i");
});
$("#green").live("click",function()
{
$("#webhost_navn").val("");
});
Note if the goal is to post an "i" and have nothing else as a value (ie no user input) use <input type='hidden' id=webhost_navn > and use the same jquery code as above without the need for the css.

Categories