Javascript, cloning, function and changing id's and names, any Ideas? - php

Here is my Javascript:
<script>
function disable()
{
document.getElementById("habits").disabled=true;
document.getElementById("habits2").disabled=true;
document.getElementById("exact").disabled=false;
}
function enable()
{
document.getElementById("habits").disabled=false;
document.getElementById("habits2").disabled=false;
document.getElementById("exact").disabled=true;
}
var counter =0;
var i = 0;
function duplicate() {
var original = document.getElementById('div');
var clone = original.cloneNode(true); // "deep" clone
i+=1;
clone.id = "div" + i; // there can only be one element with an ID
original.parentNode.appendChild(clone);
document.getElementById('div' + i).getElementsByTagName('select').name += '_clone' + i;
counter+=1;
}
</script>
and this is my HTML code:
<button id="button" onclick="duplicate()">Add List</button><br><br>
<form id ="form" name="search" method="post" action="test.php">
<div id="div">
<div id="d">
<select name ="select" >
...options...
</select>
</div>
Value:<input type="text" id ="exact">
From: <input type="text" id="habits">
To: <input type="text" id="habits2">
<br>
<input type="button" name="answer" value="Range" onclick="enable()" >
<input type="button" name="answer" value="Exact" onclick="disable()" >
</div>
<br><br>
<input type="submit" name ="search" value="Submit">
</form>
My issue here is that, when I clone the div id=div, all the buttons work for the original one, even the cloned buttons. Another thing is that, when I click the submit button to get the options from the drop-down list(s), but after submission, only the last drop-list is counted (cloned), but I want the original only.
Here is my page after clicking submit:
<?php
$item = $_POST["select"];
echo $item;
?>
How can I solve this? That is, changing the id's and names, and functions working with the cloned elements?

First of all, don't use id's if you want to duplicate things. Use and select by class (I strongly recommend to use jQuery), and use name="some_name[]"
To solve your problem you can do: onclick="javascript:enable(this)" or, if you decide to use jQuery, use `onclick="javascript:jQuery(this)", and then you search for siblings of the current element (don't know the pure js syntax, just the jquery one, if you need help with jquery let me know).
Hope this helps, good luck.

try this one. i have changed the function by adding a line
function duplicate() {
var original = document.getElementById('div');
var clone = original.cloneNode(true); // "deep" clone
i+=1;
clone.attr("id",replace(clone.attr("id"),"div"+i));// change the id of clone div
// clone.id = "div" + i; // there can only be one element with an ID
original.parentNode.appendChild(clone);
document.getElementById('div' + i).getElementsByTagName('select').name += '_clone' + i;
counter+=1;
}

Related

How to access form element xyz[] in Javascript?

I have code that will automatically add a new similar row defined in form by clicking add button.
<html>
<body>
<form>
<input type="text" name="quantity[]" class="input_text" id="pro"/>
</form>
</body>
</html>
Now I want to access different values of quantity[] in javascript function .
How to access this different values of quantity[] in javascript using it's ID or Name Attribute.
<script>
function abc() {
var id = document.getElementById("pro").value;
}
</script>
You can do something like this.
html:
<form>
<input name="p_id[]" value="0"/>
<input name="p_id[]" value="1"/>
<input name="p_id[]" value="2"/>
</form>
javascript:
var p_ids = document.forms[0].elements["p_id[]"];
alert(p_ids.length);
for (var i = 0, len = p_ids.length; i < len; i++) {
alert(p_ids[i].value);
}
The way to do that with plain JavaScript is to get all the elements with an specific name, as following:
var fields = document.getElementsByName('quantity[]');
Should you want to access an specific value, you could do that as well:
console.log(fields[0].value); // foo
Here's a jsfiddle with a code sample.
HTML:
<form name="order">
<input type="text" name="quantity[]" class="input_text" />
<input type="text" name="quantity[]" class="input_text" />
<input type="text" name="quantity[]" class="input_text" />
</form>
JS:
var elements = document.forms['order'].elements['quantity[]'];
console.log(elements[1].value); // outputs the value of the 2nd element.
demo: http://jsfiddle.net/NDbwt/
$('input[name=quantity]').each(function(){
alert($(this).val())
});
First: id must be unique on page. Otherwise document.getElementById will always return first spotted element with requested id.
In your case, you may do next:
var id = document.getElementsByName("quantity[]")[0].value;
But more safely (I'm not sure if order of items in returned array will always be the same as order in which elements are added) would be to generate ids like pro_0, pro_1, pro_2 etc
You're probably confused by the fact that PHP reads form fields as arrays when you use square brackets on their name. That's only a PHP trickā€”for JavaScript, [] does not have any special meaning and you can read the items in the usual way:
var values = [];
var fields = document.getElementsByName("quantity[]");
for (var i = 0, len = fields.length; i < len; i++) {
values.push(fields[i].value);
}
alert("Values:\n" + values.join("\n"));
See it in action.

Dynamically added input fields not getting posted?

The code below consists of invoice-lines that contain some input fields that the user can fill out. The initial number of input lines is 20. Users will often need to add more lines to the invoice by clicking the "Add lines" button. Every click of this button uses Javascript to append more lines to the invoice.
The problem is when the form gets submitted only the first 20 lines seem to get submitted. All the javascript appended invoice lines are ignored and never POSTed.
I have been trying to work out this problem for quite a while now, I was wondering if someone can guide me as to how to go about implementing this correctly?
Many thanks in advance.
Markup / PHP
<?php
for($i=0; $i < 20; $i++){
echo '
<div class="invoice-line">
<div class="prod-id-cell"><input name="rows['.$i.'][id]" type="text" class="prod-id-input">
<div class="smart-suggestions">
<!-- RESULT SUGGESTIONS WILL POPULATE HERE --> </div>
</div>
<div class="prod-name-cell">
<input type="text" name="rows['.$i.'][name]" class="prod-name-input"/> <div class="smart-suggestions">
<!-- RESULT SUGGESTIONS WILL POPULATE HERE -->
</div>
</div>
<div class="price-cell"><input name="rows['.$i.'][price]" class="price-input" type="text" /></div>
<div class="quantity-cell"><input name="rows['.$i.'][quantity]" type="text" class="quantity-input"></div>
<div class="unit-price-cell"><input name="rows['.$i.'][unit-price]" class="unit-price-input" type="text" /></div>
<div class="num-kits-cell"><input name="rows['.$i.'][num-kits]" class="num-kits-input" type="text" /></div>
<div class="amount-cell"><input name="rows['.$i.'][amount]" class="amount-input" type="text" readonly="readonly" /></div>
</div>';
}
?>
Javascript
//**ADD 5 LINES**//
$('.invoice-links div').on("click", ".add-five-trigger", function(){
for(var i=0; i < 5; i++){
var invoiceLine = $(".invoice-line").first().clone( true, true );
$(invoiceLine).insertAfter(".invoice-line:last");
$(".invoice-line:last").find('input').val('').attr('disabled','disabled');
}
});
You forgot to change the name attributes of the cloned inputs. They would overwrite previous fields.
Use this:
var invoiceLine = $(".invoice-line").last();
var newLine = invoiceLine.clone( true, true );
invoiceLine.after(newLine);
newLine.find('input').each(function() {
if (this.type == "text")
this.value = "";
this.name = this.name.replace(/rows\[(\d+)\]/, function(m, num) {
return "rows["+(+num+1)+"]";
});
this.disabled = true;
});
The values are not being posted because you are disabling them. Input elements with disabled attribute don't get posted.
Also, always make sure that elements have unique ids and names. Elements without names don't get posted.
You are not giving new names to the elements you create. You are also disabling them.
$(".invoice-line:last").find('input').val('').attr('disabled','disabled');
Disabled form inputs will never be submitted with the form.

jquery getting all the values of the nearest element

<ul><li class="rjust">
Edit
<input type="hidden" class="video_title" value="test123">
<input type="hidden" class="video_description" value="Sample Description">
<input type="hidden" class="video_tags" value="Adjust">
<input type="hidden" class="video_tags" value="TXV">
</li>
<li class="rjust">
Edit
<input type="hidden" class="video_title" value="another_test">
<input type="hidden" class="video_description" value="descriptme agian">
<input type="hidden" class="video_tags" value="tag1">
<input type="hidden" class="video_tags" value="tag2">
</li></ul>
When I click on the "Edit" a href, I want to get all the values of the class "video_tags" nearest to it.
Example when the 1st "Edit" is being click (id="4f80a4b5"), I want to get all the value of the "video_tags" which is "Adjust", "TXV".
On the other hand, when I click on the other "Edit" (id="235235"), all the value of "video_tags" that I should get is "tag1","tag2" since it obviously it is near to it.
Take note that the class "video_tags" is flexible, it could have many classes, my example has just only 2 video_tags per li.
Kindly please help me with this matter. Any help would be greatly appreciated and rewarded! Thanks :)
You can try this
var tags;
$(".edit-video-lightbox").click(function() {
tags = [];
$(this).siblings('.video_tags').each(function() {
tags.push($(this).val());
});
});
There is a .siblings() method for this in jQuery:
$('.edit-video-lightbox').click(function() {
$(this).siblings('input.video_tags').each(function() {
//this keyword refers to sibling element
//user this.value to retrieve element's value
});
});
Yeah, I know, three answers already. But just wanted to highlight both the new on method introduced in jQuery 1.7, as well as the nifty map method from jQuery 1.0:
function getVal(elem) {
return elem.value;
}
function getVals(e) {
var tags = $(e.target).siblings('.video_tags'),
values = $.map(tags, getVal);
e.preventDefault();
// do whatever you want with `values` here
}
$('ul').on('click', '.edit-video-lightbox', getVals);

Using a JS variable inside php code?

I'm attempting to make it so that when you click a button, it'll add new fields to the page. I know that onclick can only take JS functions so I decided to try my luck making a JS script. At first I had tried to do
<html>
<head><title>multiple line test</title><head>
<body>
<script type="text/javascript">
var texters='';
var num=0;
function newInput(nomnom)
{
texters='';
num=nomnom+1;
for (var i=0; i<nomnom; i++)
{
texters+='<p>\
Please specify a file, or a set of files:<br>\
<input type="file" size="40">\
</p>\
<p>\
Caption : <br> \
<input type="text" size="30">\
</p>';\
}
document.write(texters+'<div>\
<input type="submit" value="Send">\
</div>\
</form>\
<br>' + '<input type="button" value="new entry" onclick="newInput(num)">' . '</body></html>');
}
newInput(num);
</script>
</body>
</html>
but that didn't work. So I tried instead to add a little bit of php being that I know it better. I tried this :
<html>
<head><title>multiple line test</title><head>
<body>
<script type="text/javascript">
var texters='';
var num=0;
function newInput(nomnom)
{
document.write(<?php
tex='';
for (var i=0; i<=(nomnom); i++)
{
tex.='<p>
Please specify a file, or a set of files:<br>
<input type="file" size="40">
</p>
<p>
Caption : <br>
<input type="text" size="30">
</p>';
}
echo tex . '<div>
<input type="submit" value="Send">
</div>
</form>
<br>' . '<input type="button" value="new entry" onclick="newInput(num)">' . '</body></html>';
?>);
}
newInput(num);
</script>
</body>
</html>
But I know that won't work because I can't get the variable I'm using for the number of fields to use out of the JS and into the PHP. Is there any way I could force JS to put that number in $_POST so I can retrieve it without having to make another form? Or is there a better way to do what I'm trying to do?
You can set a hidden input field on the form, and have the Javascript populate that.
You should try using jquery http://jquery.com/ or a simialr scripting library as it will make manipulating the DOM much easier. Using jquery you can create an onClick function that will do what you want in a few lines of code:
var onClickAddInput = function()
{
$('div#your_div_id').append('<input type="text" size="30" />');
}
If you need to add more input boxes you could loop the append statement and give the individual input boxes ids that equal the loop number.
As commented PHP is for serverside, javascript for clientside. html is the ui elements which either can create. If you need something done on the server, do it in PHP, if it needs to be done on the client, do it in javascript. Here is a sample of javascript for you.
function newInput(nomnom)
{
var tex='';
for (var i=0; i<=(nomnom); i++)
{
tex+='<p>Please specify a file, or a set of files:';
tex+='<br/><input type="file" size="40"></p>';
tex+='<p>Caption :';
tex+='<br/><input type="text" size="30"></p>';
}
document.getElementById('form_id').innerHTML += tex;
}
when this function is called, it will create a number of new inputs and add them to the form with the id "form_id".

Allow user to create and submit up to 5 text boxes with jquery, and parse them into one array in php?

Is it possible?
I want a user to post an array full of 1-5 pieces of data.
At first there would be only one text field on show, but on clicking a 'plus' icon next to it, it would create another text field below it for more user input.
I would also want to have a delete icon next to text boxes 2-5, to remove them if necessary.
My JQuery knowledge is limited, and I can work out how to append text boxes to a list, but not to keep track of them/delete them. Ideally I would also want to pass them as an array to php, so I can easily loop through them.
<input type="text" size="15" maxlength="15" name="1"><img src="add.png" onclick="add();">
<!-- Below is hidden by default, and each one shows on click of the add image -->
<input type="text" size="15" maxlength="15" name="2"><img src="delete.png" onclick="delete(2);">
<input type="text" size="15" maxlength="15" name="3"><img src="delete.png" onclick="delete(3);">
<input type="text" size="15" maxlength="15" name="4"><img src="delete.png" onclick="delete(4);">
<input type="text" size="15" maxlength="15" name="5"><img src="delete.png" onclick="delete(5);">
jQuery clone() is very handy for this. A small example how it could be done (working example on jsfiddle)
<ul>
<li><input type="text" name="textbox[]" /></li>
</ul>
<input type="button" id="addTextbox" value="Add textbox" />
<script type="text/javascript">
$(function(){
$('#addTextbox').click(function(){
var li = $('ul li:first').clone().appendTo($('ul'));
// empty the value if something is already filled in the cloned copy
li.children('input').val('');
li.append($('<button />').click(function(){
li.remove();
// don't need to check how many there are, since it will be less than 5.
$('#addTextbox').attr('disabled',false);
}).text('Remove'));
// disable button if its the 5th that was added
if ($('ul').children().length==5){
$(this).attr('disabled',true);
}
});
});
</script>
For the server-side part, you could then do a foreach() loop through the $_POST['textbox']
As long as you give each text box a name like "my_input[]", then when the form is submitted, PHP can get the answer(s) as an array.
$_REQUEST['my_input']; would be an array of the values stored in each text box.
Source: Add and Remove items with jQuery
Add
Remove
<p><input type="text" value="1" /></p>
<script type="text/javascript">
$(function() { // when document has loaded
var i = $('input').size() + 1; // check how many input exists on the document and add 1 for the add command to work
$('a#add').click(function() { // when you click the add link
$('<p><input type="text" value="' + i + '" /></p>').appendTo('body'); // append (add) a new input to the document.
// if you have the input inside a form, change body to form in the appendTo
i++; //after the click i will be i = 3 if you click again i will be i = 4
});
$('a#remove').click(function() { // similar to the previous, when you click remove link
if(i > 1) { // if you have at least 1 input on the form
$('input:last').remove(); //remove the last input
i--; //deduct 1 from i so if i = 3, after i--, i will be i = 2
}
});
$('a.reset').click(function() {
while(i > 2) { // while you have more than 1 input on the page
$('input:last').remove(); // remove inputs
i--;
}
});
});
</script>
You will need to create DOM elements dynamically. See how it is done for example in this question. Notice that
document.createElement
is faster then using jquery's syntax like
$('<div></div>')
Using that technick, you could create inputs like
<input name="id1"/>
<input name="id2"/>
<input name="id3"/>
<input name="id4"/>
<input name="id5"/>
On submitting your form you'll get all them in your query string like
...id1=someval1&id2=someval2&...
Having that, you could process this query as you want on server side.
<form method="POST" id="myform">
<input />
Add textbox
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
$(document).ready(function(){
$('#add_textbox').click(function(){
var form=$(this).closest('form');
var count=form.find('input').length();
form.append('<div class="removable_textbox"><input />delete</div>');
$('.delete_input').click(function(){
$(this).find('.removable_textbox').remove();
return false;
});
return false;
});
$('#myform').submit(function(){
var i=1;
$(this).find('input').each(function(){
$(this).attr('name','input-'+i);
i++;
})
});
});
</script>
<?php
if(isset($_POST['input-1'])){
$input_array=$_POST;
}
?>
something like this?
I wrote a litte jQuery plugin called textbox. You can find it here: http://jsfiddle.net/mkuklis/pQyYy/2/
You can initialize it on the form element like this:
$('#form').textbox({
maxNum: 5,
values: ["test1"],
name: "textbox",
onSubmit: function(data) {
// do something with form data
}
});
the settings are optional and they indicate:
maxNum - the max number of elements rendered on the screen
values - an array of initial values (you can use this to pass initial values which for example could come from server)
name - the name of the input text field
onSubmit - onSubmit callback executed when save button is clicked. The passed data parameter holds serialized form data.
The plugin is not perfect but it could be a good start.

Categories