run js function on dynamically created select menu - php

i have this code:
This is the addOptions function
<script>
var values = <?php
$sql="SELECT * FROM billing_sagenominalcodes order by code ASC";
$rs=mysql_query($sql,$conn) or die(mysql_error());
$nominalcodes = array();
while($result=mysql_fetch_assoc($rs))
{
$nominalcodes[] = $result['code'];
}
echo json_encode($nominalcodes);
?>;
var names = <?php
$sql="SELECT * FROM billing_sagenominalcodes order by code ASC";
$rs=mysql_query($sql,$conn) or die(mysql_error());
$nominalcodesname = array();
while($result=mysql_fetch_assoc($rs))
{
$nominalcodesname[] = $result['code'] . ' - ' . $result['name'];
}
echo json_encode($nominalcodesname);
?>;
function addOptions(select, values)
{
for (var i=0, iLen=values.length; i<iLen; i++)
{
select.appendChild(new Option(names[i],values[i]));
}
}
</script>
then the add row function
<script language="javascript" type="text/javascript">
var i=1;
function addRow()
{
var tbl = document.getElementById('table1');
var lastRow = tbl.rows.length;
var iteration = lastRow - 1;
var row = tbl.insertRow(lastRow);
var sagenominalcodeCell = row.insertCell(3);
var elSageNominalCode = document.createElement('select');
elSageNominalCode.type = 'select';
elSageNominalCode.name = 'sagenominalcode' + i;
elSageNominalCode.id = 'sagenominalcode' + i;
sagenominalcodeCell.appendChild(elSageNominalCode);
i++;
}
</script>
and then the HTML
<select name="sagenominalcode" id="sagenominalcode">
<script>addOptions(document.getElementById('sagenominalcode'), values);</script>
</select>
<input type="button" value="Add" onclick="addRow();" />
it adds the new rows ok but its no populating the select menu with the addOptions function.
is there any way to make it run that function once the new row/select menu has been dynamically created and then the same for all the others created when the addRow function is called?

So, reading your code a little bit more, I see you have
new Option(names[i],values[i])
My question to you is what does new Option return? I don't see code for it anywhere in your question.
Take a look at the spec for appendChild :
https://developer.mozilla.org/en-US/docs/DOM/Node.appendChild
It needs an element passed in. What you want to do is make a new element using the createElement() function like so:
var option = document.createElement("option");
And then edit the inner html to be what ever you need like this:
option.innerHTML = "your option content here";
Then pass the element in to the append child function:
appendChild(option);
Use jQuery here instead of straight js. My bet is that your listener for click is only bound to the items that are present on the page when it is created. If you set up a listener through jQuery, then it will fire even on components that are dynamically added.
Also from a code structuring stand point, be very careful about writing js with php. Although it sounds fun (like doing drugs in highschool) it is dangerous, frustrating and leads to untestable code (like doing drugs in highschool does).

Related

Redefine ID with ampersand

Working with Sly's scrolling codes (http://darsa.in/sly/).
Having multiple Sly carousels on a page, I need to fix the ID of the frame
I generate them with '#=basic-XXX', where XXX is the record of the album.
the standard code is this:
var $frame = $('#basic');
var $slidee = $frame.children('ul').eq(0);
var $wrap = $frame.parent();
I try to read the ID, including the attached record number from the database.
var $frame = $("[id^=basic-]"); // start with...
// trying these two lines, but they FAIL
var num = $frame.slice(7);
var $frame = $("#basic-"+num);
//from here $frame should be redefined as #basic-THENUMBER
var $slidee = $frame.children('ul').eq(0);
var $wrap = $frame.parent();
Any idea how I can update var $frame with the ID so it works for the rest of the script?
$("[id^=basic-]") will return the elements that match the selector and you can then use .attr('id') to get the first element's id value. If there is only one element with an id starting with basic- then this will work:
$frame = $("[id^=basic-]").attr('id');
Note that when you use String.slice, character positions start at 0, so I think you probably want:
var num = $frame.slice(6);
See this demo:
var $frame = $("[id^=basic-]").attr('id');
console.log($frame);
var num = $frame.slice(6);
console.log(num);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<span id="basic-355">hello world!</span>
</div>
If you have multiple elements that have matching id's you will need to iterate them using .each or similar:
var $frames = $("[id^=basic-]");
$frames.each(function () {
let id = $(this).attr('id');
console.log(id);
let num = id.slice(6);
console.log(num);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<span id="basic-355">hello world!</span>
<span id="basic-562">hello world!</span>
</div>

JQuery for-loop with variable

I have a table out of different MySQL data. I want to highlight cells with the same ID in it on hover. I did that with a simple jQuery, the script is almost working but you see I've got the var nr and want the integer i to be added to the class string. What is my mistake, why isn't it working? If you change the var nr = '.id_' + i; to a static variable like var nr = '.id_2'; it is working.
for (i = 0; i < 10; i++) {
var nr = '.id_' + i;
var bgcol = $(nr).css('backgroundColor');
$(nr).hover(
function(){
$(nr).css({"background":"yellow"});
},function(){
$(nr).css({"background":bgcol});
});
}
http://jsfiddle.net/Nkdny/210/
Solution, thanks to Karl-André Gagnon: http://jsfiddle.net/Nkdny/215 Look in the comments for details.
You're missing an echo in front of your php statement.
<?php echo $amount; ?>

Fixing jQuery plugin to handle duplicating nested fields with unique ID's

I have a quick question for you guys here. I was handed a set of lead generation pages and asked to get them up and running. The forms are great, expect for one small issue... they use the jQuery below to allow users to submit multiple instances of a data set by clicking an "Add another item" button. The problem is that the duplicated items are duplicated EXACTLY. Same name, id, etc. Obviously, this doesn't work when attempting to process the data via PHP, as only the first set is used.
I'm still learning jQuery, so I was hoping that someone could point me in the right direction for how to modify the plugin below to assign each duplicated field an incremental integer on the end of the ID and name assigned. So, the fields in each dataset are Role, Description, Age. Each additional dataset will use the ID & name syntax of fieldname#, where # represents numbers increasing by 1.
Thanks in advance for any advice!
/** https://github.com/ReallyGood/jQuery.duplicate */
$.duplicate = function(){
var body = $('body');
body.off('duplicate');
var templates = {};
var settings = {};
var init = function(){
$('[data-duplicate]').each(function(){
var name = $(this).data('duplicate');
var template = $('<div>').html( $(this).clone(true) ).html();
var options = {};
var min = +$(this).data('duplicate-min');
options.minimum = isNaN(min) ? 1 : min;
options.maximum = +$(this).data('duplicate-max') || Infinity;
options.parent = $(this).parent();
settings[name] = options;
templates[name] = template;
});
body.on('click.duplicate', '[data-duplicate-add]', add);
body.on('click.duplicate', '[data-duplicate-remove]', remove);
};
function add(){
var targetName = $(this).data('duplicate-add');
var selector = $('[data-duplicate=' + targetName + ']');
var target = $(selector).last();
if(!target.length) target = $(settings[targetName].parent);
var newElement = $(templates[targetName]).clone(true);
if($(selector).length >= settings[targetName].maximum) {
$(this).trigger('duplicate.error');
return;
}
target.after(newElement);
$(this).trigger('duplicate.add');
}
function remove(){
var targetName = $(this).data('duplicate-remove');
var selector = '[data-duplicate=' + targetName + ']';
var target = $(this).closest(selector);
if(!target.length) target = $(this).siblings(selector).eq(0);
if(!target.length) target = $(selector).last();
if($(selector).length <= settings[targetName].minimum) {
$(this).trigger('duplicate.error');
return;
}
target.remove();
$(this).trigger('duplicate.remove');
}
$(init);
};
$.duplicate();
Add [] to the end of the NAME attribute of the input field so for example:
<input type ="text" name="name[]"
This way your $POST['name'] will hold an array of strings. For that element. It will be an array with keys that are numbers from 0 to however many items it holds.

<input></input> in innerHTML not working

I created a dropdown list with javascript and I populate it getting data from a MySQL database.
The problem that I have is that I can't place the dropdown list in the innerHTML code.
This is what I wrote to create the dropdown list with JS:
var mySpan = document.getElementById('myDiv');
var myLine = document.getElementById('testcat');
myLine.value++;
// Create select
var selection = document.createElement('select');
selection.setAttribute('name',"category[]");
mySpan.appendChild(selection);
// Create Option
createSelectOption(selection);
// Create the container
var ni = document.getElementById('myDiv');
ni.setAttribute('style', 'width:790px;');
...........
...........
Then I create other things and to create the HTML code, I use:
newdiv.innerHTML = '<div class="table">.........</div>';
ni.appendChild(newdiv);
This is the part of HTML:
// test dropdown list
<input name="testcat" id="testcat" type="hidden" value="0" />
<div id="myDiv"></div>
I tested my dropdown list as you can see in the code above, and it works if I declare <input name="testcat" id="testcat" type="hidden" value="0" /> in the HTML (I mean in the <body></body>), but if I use the same code in the innerHTML, FireBug tells me: "myLine is null; myLine.value++;".
Any help?
You can't assign an element with an ID using innerHTML as text - the ID won't register on the DOM. You need to first create the element, assign it the ID and then put that element in the DOM.
You might find this easier using jQuery:
var input = document.createElement("input");
input.id="testcat";
input.innerHTML = "testcat" ;
$('somediv').appendChild(input);
this is what I did in my old code:
var selectcat = document.createElement("select");
selectcat.name = "category[]";
selectcat.options[0] = new Option("","");
selectcat.options[1] = new Option("cat1","cat1");
selectcat.options[2] = new Option("cat2","cat2");
..........
..........
selectcat.options[12] = new Option("cat1","cat12");
And the used:
newdiv.innerHTML = '<div class="table"><ul><li><select name="category[]"><option value=""></option><option value="cat1">cat1</option><option value="cat2">cat2</option></select></li></ul></div>';
But now I have to get the values from a MySQL database.
So I created this function:
function createSelectOption(element)
{
var objSelect = ele;
var Item = new Option("", "");
objSelect.options[objSelect.length] = Item;
<?
while($categ = mysql_fetch_array($resultf_categ))
{
?>
var Item = new Option("<?=$categ["cat_name"];?>", "<?=$categ["cat_name"];?>");
objSelect.options[objSelect.length] = Item;
<?
}
?>
}
But still don't understand how can I use directly in my innerHTML.
Sorry for the stupid questions, but I am really stucked here.

Total value with JavaScript and PHP

I'm using this form script to automatically calculate totals. Now I need to get that total and add it to a database via PHP and MySQL.
I don't know how to 'name' the totalPrice div, so that I can pass its value to the database.
Edit:
I'm still not getting results in the database. I'm now using $_POST[totalValue] for the field set and totalPrice for the field name.
HTML:
<div id="totalPrice"></div></div>
<input type="hidden" name="totalValue" id="totalValue" />
JavaScript:
$("#vendorform").submit(function(){
var totalValue = document.getElementById('totalValue');
totalValue.value = vendorPrice; //the actual total value
});
function calculateTotal()
{
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var vendorPrice = getTentPrice() + getElecPrice() + getPropanePrice();
//display the result
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price Vendor $"+vendorPrice;
}
The vendorPrice variable is not available outside the scope of the function calculateTotal. You could make vendorPrice a global variable, but that's a bit of an ugly hack.
Alternatively, you could do something like this:
function calculateTotal()
{
var vendorPrice = getTentPrice() + getElecPrice() + getPropanePrice();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price Vendor $"+vendorPrice;
return vendorPrice; // <-- ADDED
}
And this:
$("#vendorform").submit(function(){
var totalValue = document.getElementById('totalValue');
totalValue.value = calculateTotal(); // <-- CHANGED
});
This way, you assign the value that is now returned by calculateTotal() to totalValue.value.
By the way: since it looks like you're already using jQuery, you can rewrite your code like this:
// [...]
var divobj = $('#totalPrice');
divobj.css('display', 'block');
divobj.text("Total Price Vendor $"+vendorPrice);
// [...]
var totalValue = $('#totalValue');
totalValue.val(calculateTotal());
This makes it a bit more readable (although that's debatable) and a bit more cross-browser reliant. jQuery has great docs (e.g. the documentation on .val()). If you're going to use jQuery more often I can highly recommend bookmarking the docs and skimming through them.
Using jQuery:
$("#cakeform").submit(function(){
var price = $("#totalPrice").text().replace(/[\s\S]+\$/,"")
$("#cakeForm").append('<input type="hidden" name="estimated_price" value="' + price + '" />')
})
But as #nick-rulez pointed out, is usually not a good idea to save calculated values in a database.
You can set the value to:
<input type="hidden" name="totalValue" id="totalValue" />
Which you have to put inside your <form>...</form>.
When you submit the form you're going to receive input's value.
You can set the value to the hidden field with this sniped:
JS
var totalValue = document.getElementById('totalValue');
totalValue.value = myValue; //myValue is the total
JavaScript:
function calculateTotal()
{
var Price = getTshirtPrice() + getTshirtType() + getTshirtColour() +
getTextColour();
var divobj = document.getElementById('textbox');
divobj.value = "Total Price For the T-shirt: £"+Price;
return Price;
}
HTML:
<div id="totalPrice"><input type="text" id="textbox"></div>
Do that. It works perfectly fine.

Categories