I edited my question and started afresh.
I have a html form which contains 2 dropdown lists (#selProvincie, #selRegiune). when a new option from List1 is selected by user, List2 must change accordingly. The lists are generated thru PHP from MySQL querying two tables that have a foreign key relationship (this code is not shown for brevity).
HTML
<div class="input_frm">
<form method="post" action="<?php print data_clean($_SERVER["PHP_SELF"]);?>">
<table class="input_tbl">
<tr>
<td class="a">Select province</td>
<td class="b"><select id="selProvincie" name="Alfa" onchange="provincieChg()"></select></td>
<td class="c"><input class="button_face" type="submit" value="Submit"></td>
</tr>
<tr>
<td class="a">Select region</td>
<td class="b"><select id="selRegiune" name="Beta" onchange="regiuneChg()"></select></td>
<td class="c"></td>
</tr>
</table>
</form>
JavaScript
$(document).ready(function()
{
$.getJSON("/scripts/031A_GetProvincie.php", success = function(data)
{
var str_options = "";
for (var i=0; i < data.length; i++)
{
str_options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
$("#selProvincie").append(str_options);
$("#selProvincie").change();
});
$("#selProvincie").change(function()
{
$.getJSON("/scripts/031B_GetProvRegiune.php?provincie=" + $(this).val(), success = function(data)
{
var str_options = "";
for (var i=0; i < data.length; i++)
{
str_options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
$("#selRegiune").html("");
$("#selRegiune").append(str_options);
$("#selRegiune").change();
});
});
$("#selRegiune").change(function()
{
$.getJSON("/scripts/031C_GetProvRegiuneZona.php?regiune=" + $(this).val(), success = function(data)
{
var str_options = "";
for (var i=0; i < data.length; i++)
{
str_options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
});
});
});
Using the above as an example (I'm new to JavaScript) I want to write a new form, which has a text input field (Text1) inserted between List1 and List2. List2 is generated from the option selected in List1 AND the text in Text1. But I really don't know how to use the process the input text in JavaScript to make the whole thing work.
HTML
<div class="input_frm">
<form method="post" action="<?php print dataclean($_SERVER["PHP_SELF"]);?>">
<table class="input_tbl">
<tr>
<td class="a">Select county</td>
<td class="b"><select id="selJudet" name="Alfa" onchange="judetChg()"></select></td>
<td class="c"><input class="button_face" type="submit" value="Submit"></td>
</tr>
<tr>
<td class="a">Zone wildcard text</td>
<td class="b"><select id="selText" name="Beta" onchange="textChg()"></select></td>
<td class="c"></td>
</tr>
<tr>
<td class="a">Select zone</td>
<td class="b"><select id="selZona" name="Gamma" onchange="zonaChg()"></select></td>
<td class="c"></td>
</tr>
</table>
</form>
</div>
Question: What's the JavaScript for this form ? List2 should change anytime a change occurs in either a new option is selected from List1 OR a new the string in Text1 changes.
Your question is still a little confusing, but I'm working on the assumptions that:
Users will select a country
The available regions will be filtered to show only regions within the selected country
The regions can also be filtered by entering an optional keyword
The "zones" (?) will be filtered based on the above three selections, and displayed to the user
With that in mind, this combination should achieve what you need. I've stripped back the HTML to the bare essentials. I've also change the id of the fields to match (what I think) you're trying to achieve.
The script could be optimised further, but this example should set you on the right path, but let me know if you have additional questions.
I've created a JsFiddle demonstrating how this works.
HTML
<form method="post" action="">
Country: <select id="selectCountry" name="Alfa"></select>
<br>
Region: <select id="selectRegion" name="Gamma"></select>
<br>
Wildcard: <input id="selectText" name="Beta">
</form>
Javascript
$(document).ready(function() {
// Change to match your URL
$.getJSON("/echo/json/", function(data) {
// Override with fake data because I can't see what the PHP generates
data = ['Australia', 'Japan', 'Uganda'];
var str_options = "";
for (var i=0; i < data.length; i++) {
str_options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
$("#selectCountry").append(str_options);
});
// Filter regions based on the selected country
filterRegions = function() {
country = $("#selectCountry").val();
wildcard = $("#selectText").val();
console.log('Search for regions that match ' + country + ' and ' + wildcard);
// Change to match your PHP url
$.getJSON(" /echo/json/?country=" + country + "&wildcard=" + wildcard, function(data) {
// Override with fake data
data = ['California', 'Florida', 'Nevada'];
var str_options = "";
for (var i=0; i < data.length; i++) {
str_options += "<option value='" + data[i] + "'>" + data[i] + "</option>";
}
$("#selectRegion").html(str_options);
});
};
// Filter results based on the selected region and any text search
filterResults = function(){
country = $("#selectCountry").val();
wildcard = $("#selectText").val();
region = $("#selectRegion").val();
console.log('Search for zones that match ' + country + ' and ' + wildcard + ' and ' + region);
// Change to match your PHP url
$.getJSON("/echo/json/?country=" + country + "®ion=" + region + "&wildcard=" + wildcard, function(data) {
// Display results as you need
});
};
// Attach event handlers to relevant DOM elements (instead of using inline change="Chg()" style functions)
$("#selectCountry").on("change", filterRegions);
$("#selectText").on("keyup", filterRegions);
$("#selectRegion").on("change", filterResults);
});
Notes:
You will need to update the URLs being used for each getJson() request. The URLs will need to pass the values from the <input> and <select> tags as $_GET variables.
In my example, I've used fake data as an example, so remove this from your script when testing it. E.g.
data = ['California', 'Florida', 'Nevada'];
You do not need to specify $_SERVER['PHP_SELF'] because a <form> tag defaults to itself in the absence of any action attribute. E.g.
<form method="post" action="<?php print data_clean($_SERVER["PHP_SELF"]);?>">
Can simply be:
<form method="post" action="">
Related
Preface:
I have an HTML table where user fills in Name and URL of social networks where they have account. Each row has a checkbox. With the help of jQuery and JavaScript, on pressing Add Row button, a row is dynamically added to the table and on pressing delete row button those rows are deleted for which checkbox is checked.
Objective:
When selected rows are deleted, I want to assign id to input elements and checkboxes of every remaining row in serial manner, so that the rows are always serially sound.
Problem:
I am not able to find what makes it throw error, as childNodes[] do not seem to lead to unavailable element. Please help!
Snippet:
// variable to keep track of rows(records)
var social_recs_num = 1;
$(document).ready(function () {
$("#social_add_rec").click(function () {
social_recs_num++;
var markup = "<tr> <th scope=\"row\"> <div class=\"form-group\"> <div class=\"form-check\"> <input type=\"checkbox\" class=\"form-check-input\" id=\"social_rec" + social_recs_num + "\" name=\"social_rec\"> <label class=\"form-check-label\" for=\"social_rec" + social_recs_num + "\"> " + social_recs_num + "</label> </div></div></th> <td> <div class=\"form-group shadow-sm\"> <label for=\"name_social" + social_recs_num + "\">Select or Type</label> <input type=\"text\" list=\"name_social" + social_recs_num + "\" class=\"form-control\" placeholder=\"Name\"> <datalist id=\"name_social" + social_recs_num + "\"> <option value=\"Wikipedia\">Wikipedia</option> <option value=\"Youtube\">Youtube</option> <option value=\"Facebook\">Facebook</option> <option value=\"Twitter\">Twitter</option> <option value=\"Pinterest\">Pinterest</option> </datalist> </div></td><td> <div class=\"form-group shadow-sm\"> <textarea class=\"form-control\" id=\"url_social" + social_recs_num + "\" cols=\"30\" rows=\"1\" placeholder=\"URL\"></textarea> </div></td></tr>"; //in case of id we need to do it like: "min_sysreq" +social_recs_num...as social_recs_num has been incremented priorly it will be the row number of row to be added
$("table tbody").append(markup);
});
// Find and remove selected table rows...only condition is that there must be present attribute name='sysreq_rec' in input element for checkbox of every row
$("#social_delete_rec").click(function () {
$("table tbody").find('input[name="social_rec"]').each(function () {
if ($(this).is(":checked")) {
social_recs_num = social_recs_num - $(this).length;
$(this).parents("tr").remove();
}
});
// to be run when a row is deleted...this assigns ids to input elements in serial manner
var table = document.getElementById("mytab1");
var rowCount = table.rows.length;
// i has been initiated with 1, as header row is the 0th row
for (var i = 1; i < rowCount; i++) {
var row = table.rows[i];
// on this line, getting error: `Uncaught TypeError: Cannot read property 'id' of undefined`
row.childNodes[0].childNodes[0].childNodes[0].childNodes[0].id = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].for = "social_rec" + i;
row.childNodes[0].childNodes[0].childNodes[0].childNodes[1].innerHTML = " " + i;
row.childNodes[1].childNodes[0].childNodes[0].for = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[1].list = "name_social" + i;
row.childNodes[1].childNodes[0].childNodes[2].id = "name_social" + i;
row.childNodes[2].childNodes[0].childNodes[0].id = "url_social" + i;
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="mytab1">
<thead>
<tr>
<th scope="col">
#
</th>
<th scope="col">
Name
</th>
<th scope="col">
URL
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<div class="form-group">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="social_rec1" name="social_rec">
<label class="form-check-label" for="social_rec1"> 1</label>
</div>
</div>
</th>
<td>
<div class="form-group shadow-sm">
<label for="name_social1">Select or Type</label>
<input type="text" list="name_social1" class="form-control" placeholder="Name">
<datalist id="name_social1">
<option value="Wikipedia">Wikipedia</option>
<option value="Youtube">Youtube</option>
<option value="Facebook">Facebook</option>
<option value="Twitter">Twitter</option>
<option value="Pinterest">Pinterest</option>
</datalist>
</div>
</td>
<td>
<div class="form-group shadow-sm">
<textarea class="form-control" id="url_social1" cols="30" rows="1" placeholder="URL"></textarea>
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="button" id="social_add_rec">Add Row</button>
<button class="btn btn-primary" type="button" id="social_delete_rec">Delete Row</button>
P.S. :
I have used jQuery and Bootstrap.
this question seemed close, but I think I don't have the same mistake.
Edit:
I need to display(or store) inputs by user, for which I wrote following JavaScript code.
var social = function () {
var val = "social:\n";
for (x = 1; x <= social_recs_num; x++) {
//where social_recs_num is number of rows
val = val + "\s\s-\n";
val = val + "\s\s\s\s" + "name: " + getElementById("name_social" + x) + "\n";
val = val + "\s\s\s\s" + "url: " + getElementById("url_social" + x) + "\n";
}
return val;
}
function social returns the value input by user in YAML format. For this code, when selected rows are deleted, I want to assign id to input elements and checkboxes of every remaining row in serial manner.
The Problem:
The issues you are seeing is because you are trying to get the 'childNodes' property of an html element. In order to access that property, you would have to cast the element as a jQuery object by adding '$( )' around it. In this case, that would be '$(row)'.
However, if you do that with your code, you still get errors because of the mess of nested .childNodes[0]. You could get it working using that existing code, however...
Suggested Refactoring:
...As other stated, there are more elegant ways to approach this problem. There are a number of ways you could tackle it, but given your current html I would refactor to something like this:
//...
// to be run when a row is deleted...this assigns ids to input elements in serial manner
$('#mytab1 tbody tr').each(function() {
var rowNum = $(this)[0].rowIndex;
var formcheck = $(this).find('.form-check');
formcheck.find('.form-check-input')[0].id = 'social_rec' + rowNum;
formcheck.find('.form-check-label')[0].for = 'social_rec' + rowNum;
formcheck.find('.form-check-label')[0].innerHTML = ' ' + rowNum;
var formName = $(this).find('td')[0];
$(formName).find('label')[0].for = 'social_rec' + rowNum;
$(formName).find('input')[0].list = 'social_rec' + rowNum;
$(formName).find('datalist')[0].id = 'social_rec' + rowNum;
var formUrl = $(this).find('td')[1];
$(formUrl).find('textarea')[0].id = 'social_rec' + rowNum;
});
//...
This replaces your for loop with a jquery .each loop and then uses the .find() function to loop up each control you want to manipulate. You'll also note that it is using the rowIndex() function to determine what number to assign the row.
I think the advantage to using an approach like this is that it's much easier to read the code and determine what controls are being affected. You could also additionally refactor your html to use classes that are unique to the controls you want to target, then you could just use the class selector to change those controls.
Hope that helps!
Hello everyone I'm still new to JS, so I want to ask about calling a function when form is submitted.
[update] Form
<div id="dashboard-side">
<form id="report" class="form-horizontal" method="post" action="<?= site_url('api/load_report') ?>"> <!-- onsubmit="location.reload()" -->
<fieldset>
<div class="control-group center_div">
<label class="control-label">Sales Name</label>
<div class="controls">
<input type="text" name="sales_name" class="form-control input-xlarge txt-up" value="<?php echo set_value('cust_name'); ?>" placeholder="Enter Customer Name" style="height: 30px;"/>
</div>
</div>
<div class="control-group center_div">
<div class="controls form-inline">
<input id="get_report" type="submit" class="btn btn-success btn-inline " value="Get Report" style="width:110px; margin-left: -155px;"/>
</div>
</div>
<table border="1" width="100%" style="background-color: #dfe8f6;">
<tr>
<td width="154px"><strong>Customer Name</strong></td><td width="128px"><strong>Activity</strong></td>
<td width="244px"><strong>Detail</strong></td><td width="141px"><strong>Start Time</strong></td>
<td width="142px"><strong>Finish Time</strong></td><td width="39px" style="text-align:center"><strong>Note</strong></td>
<td style="margin-left: 50px"><strong>Action</strong></td>
</tr>
</table>
<!------------------------------------------------------------------------------------->
<div id="xreport" class="table-hover" style="background-color: #EAF2F5"></div>
</fieldset>
</form>
</div>
Controller
public function load_report() {
$this->db->where('user_id', $this->input->post('sales_name'));
$query = $this->db->get('activity');
$result = $query->result_array();
$this->output->set_output(json_encode($result)); }
JS
var load_report = function() {
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
};
If I call the function on form load it works fine, but I want to call it on form submit, how to do that?
Here is what I tried
var load_report = function () {
$("#report").submit(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
});
};
Instead of assigning the array into my #div, it shows the array data in the new blank tab like this:
my current result so far
any help would be appreciated, thanks.
Update: New calling function
var load_report = function () {
$("#report").submit(function (evt) {
evt.preventDefault();
var url = $(this).attr('action');
var postData = $(this).serialize();
$.post(url, postData, function (o) {
if (o.result == 1) {
var output = '';
Result.success('Clocked-in');
for (var i = 0; i < o.length; i++) {
output += Template.dodo(o[i]); //this data[0] taken from array in api/load_report
console.log(output);
$("#xreport").html(output);
}
} else {
Result.error(o.error);
console.log(o.error);
}
}, 'json');
});
};
with this new calling function I'm able to retrieve data from api/load_report without getting stuck on e.preventDefault or even open a new tab, I console.log and the result show correctly in the console, but it doesn't show on the div somehow.
my template.js (if needed)
this.dodo = function(obj){
var output ='';
output +='<table border=1, width=100%, style="margin-left: 0%"';
output += '<tr>';
output += '<td width=120px>' + obj.user_id + '</td>';
output += '<td width=120px>' + obj.cust_name + '</td>';
output += '<td width=100px>' + obj.act_type + '</td>';
output += '<td width=190px>' + obj.act_detail + '</td>';
output += '<td width=110px>' + obj.date_added + '</td>';
output += '<td width=110px>' + obj.date_modified + '</td>';
output += '<td style="text-align:center" width=30px>' + obj.act_notes + '</td>';
output += '</tr>';
output +='</table>';
output += '</div>';
return output;
};
Result (note, user_id = form.sales_name)
result preview
First off, I would advise against using onclick or onsubmit directly on the dom like so.
<form onsubmit="myFunction();"></form>
The biggest reason for me is that it negatively impacts readability and sometimes even future maintenance of the project . It is nice to keep html and javascript separate unless you are using a framework that provides templating features/functionality such as angularjs.
Another big one is that you can only have one in-line event present and it is easy to accidentally overwrite, which can lead to confusing bugs.
The reason it is going to a new tab is because of the .submit(). This will call your function, but then proceed with internal jQuery event handling which includes refreshing the page. There are two solutions I see most viable here.
1st Solution:
Add a event.preventDefault(); at the start of your function to stop jQuery from refreshing your page.
$("#report").submit(function(e) {
e.preventDefault();
});
2nd Solution (Likely better):
You are making an ajax call with $.get(...). You could add an event listener on a button (probably on the button used to submit the form) that fires your ajax call. Here is an example that assumes the submit button has the id of loadData.
$("#loadData").click(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
You could alway do the following:
function myFunction() {
alert("Hello! I am an alert box! in a function");
}
<form>
<input type="text" />
<input type="submit" value="submit" onclick="return myFunction();"/>
</form>
P.S. This question might be answered in this question already, add onclick function to a submit button
Try to prevent form to get submit by using preventDefault()
$("#report").submit(function(e){ //add param "e"
e.preventDefault(); //to prevent form to submit
//further code....
});
Ok just try
function mysubmit(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
as your script and
<form id="report" class="form-horizontal" onsubmit="event.preventDefault(); mysubmit();" method="post" action="<?= site_url('api/load_report') ?>">
as your form
In my program there is a table where a user can add customers and gets shown information about them. For this example the table consists of 3 rows with an input field. Adding those table rows, works.
In the first step, he should fill in the name of the customer and gets suggestions from jQuery UI Autocomplete. Works fine too.
Now the problem: When the name is filled in, an Ajax-Call gets data about the customer from a controller, the delievered data is correct. Now this data should be displayed in the input fields for that customer and that is where problem starts. I could only make it work for the next table row that directly follows, so in this case the ID is put in the right input field, but I have no Idea how to do that for the adress input field or later even more input fields and table rows.
Here is an example how it should work: First customer is John (ID: 1, Adress: Street 1) the table should look like this and work the following way:
Customer: John (via Autocomplete)
ID: 1 (Data from Ajax-Call and put in in this input field)
Adress: Street 1 (Data from Ajax-Call and put in in this input field)
Here is my HTML-Markup from the View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "")
<table id="customers">
<tr>
<td>Name of Customer:</td>
<td><input type="text" class="customername" id="customername-0" name="customername[0]" placeholder=""></td>
</tr>
<tr>
<td>ID of Customer:</td>
<td><input type="text" class="customerid" id="customerid-0" name="customerid[0]" placeholder=""></td>
</tr>
<tr>
<td>Adresss of Customer:</td>
<td><input type="text" class="customeradress" id="customeradress-0" name="customeradress[0]" placeholder=""></td>
</tr>
</table>
<button class="" type="button" id="add-customer" name="add-customer" onclick="add_customer()">Add another Customer</button>
</div>
}
JavaScript for adding table rows (not the most elegant way, I know):
<script>
// An array to store the ids of the customers
var customerIDArray = new Array();
customerIDArray.push("");
// An array to store the names of the customers
var customerNameArray = new Array();
customerNameArray.push("");
// An array to store the adresses of the customers
var customerAdressArray = new Array();
customerAdressArray.push("");
AutoCompleteCustomerName();
AutoCompleteCustomerID();
function add_customer() {
refresh_customerNameArray();
refresh_customerIDArray();
customerNameArray.push("");
customerIDArray.push("");
refresh_table();
}
function refresh_customerNameArray() {
for (i = 0; i < customerNameArray.length; ++i) {
customerNameArray[i] = $("#customername-" + i).val();
}
}
function refresh_customerIDArray() {
for (i = 0; i < customerIDArray.length; ++i) {
customerIDArray[i] = $("#customerid-" + i).val();
}
}
function refresh_customerAdressArray() {
for (i = 0; i < customerAdressArray.length; ++i) {
customerIDArray[i] = $("#customeradress-" + i).val();
}
}
function refresh_table() {
var htmlMarkup = '<table id="customers">'
if (customerNameArray.length == 1) {
htmlMarkup +=
'<tr>'+
'<td>Name of Customer:</td>'+
'<td><input type="text" class="customername" id="customername-0" name="customername[0]" placeholder="" value="' + customerNameArray[0] + '"></td>' +
'</tr>'+
'<tr>'+
'<td>ID of Customer:</td>'+
'<td><input type="text" class="customerid" id="customerid-0" name="customerid[0]" placeholder="" value="'+ customerIDArray[0] +'"></td>'+
'</tr>'+
'<tr>' +
'<td>Adresss of Customer:</td>' +
'<td><input type="text" class="customeradress" id="customeradress-0" name="customeradress[0]" placeholder=""></td>' +
'</tr>'
}
else {
for (var i = 0; i < customerNameArray.length; i++) {
htmlMarkup +=
'<tr>' +
'<td>Name of Customer:</td>' +
'<td><input type="text" class="customername" id="customername-' + i + '" name="customername['+ i +']" placeholder="" value="' + customerNameArray[i] + '"></td>' +
'</tr>'+
'<tr>' +
'<td>ID of Customer:</td>' +
'<td><input type="text" class="customerid" id="customerid-' + i +'" name="customerid['+ i +']" placeholder="" value="' + customerIDArray[i] + '"></td>' +
'</tr>'+
'<tr>'+
'<td>Adresss of Customer:</td>'+
'<td><input type="text" class="customeradress" id="customeradress-' + i + '" name="customeradress['+ i +']" placeholder=""></td>'+
'</tr>'
}
}
htmlMarkup +=
'</table>'
$("#customers").html(htmlMarkup);
AutoCompleteCustomerName();
AutoCompleteCustomerID();
}
</script>
My autocomplete-function:
<script>
function AutoCompleteCustomerName() {
$(".customername").autocomplete({
source: "/Home/AutoCompleteCustomerName",
select: function(event, ui) {
}
});
}
</script>
The Ajax-Call and the current solution for the next table row:
<script>
function AutoCompleteCustomerID()
{
$('.customername').on('focusout', function () {
var $id = $(this).closest("tr").next().find(".customerid");
var self = $(this);
$.ajax({
type: "GET",
url: "/Home/AutoCompleteCustomerID",
data: { name: $(self).closest("tr").find(".customername").val()},
contentType: "application/json",
dataType: "json",
success: function (result) {
$id.val(result.id);
}
})
});
}
</script>
So I would be thankful if you could give me an advice or a hint how this could be solved, Im pretty new to JavaScript and jQuery and still have to learn a lot.
I'm not sure it is what you need, you can try with this
var $street = $($id).closest("tr").next().find(".customeradress");
And so on with other fields which go in next lines.
NB I suppose that the related table rows are already in the page when you call the autocomplete, it seems like that.
So your autocomplete may become
<script>
function AutoCompleteCustomerID()
{
$('.customername').on('focusout', function () {
var $id = $(this).closest("tr").next().find(".customerid");
var $street = $($id).closest("tr").next().find(".customeradress");
var self = $(this);
$.ajax({
type: "GET",
url: "/Home/AutoCompleteCustomerID",
data: { name: $(self).closest("tr").find(".customername").val()},
contentType: "application/json",
dataType: "json",
success: function (result) {
$id.val(result.id);
$street.val(result.street);
}
})
});
}
</script>
Another approach would be working with data attributes and id depending on those but this may change a lot your scripts.
I'm attempting to get the data("borgid") out of the following html:
<tr style="cursor:default;" class="odd">
<td class=" ">1</td>
<td class=" ">What was your favorite childhood pet's name?</td>
<td data-borgid="1" class=" ">Generic Hospital Networks</td>
<td class=" ">5173</td>
<td style="text-align:right;" class=" "><input type="button" value="Remove" name="1" class="deleteMeCQ" style="cursor:pointer;"></td>
</tr>
I have tried both $(':nth-child(2)', $(this)).data("borgid") and $tds.eq(2).data("borgid"). Both return "undefined". Thanks in advance.
See also: Is there a way to combine $(this) with :nth-child?
var a = [];
$("#ChallengeQuestionsTable tbody tr").each(function () {
var $tds = $(this).children('td');
var questionid = '';
var question = '';
var borgid = '';
if ($tds.length == 5) {
questionid = $tds.eq(0).html();
question = $tds.eq(1).html();
borgid = $(':nth-child(2)', $(this)).data("Borgid");
a.push('{ "questionid" : "' + questionid + '", "question" : "' + question + '", "borgid" : "' + borgid + '" }');
}
});
If you want to get borgid, you can select by existing attribute:
borgid = $($(this).find("[data-borgid]").get(0)).attr("data-borgid");
In general if you want to select the nth td you could go with
$("td:eq(1)")
e.g. to select the second td.
If you want to iterate over all <tr> and its <td> and say, you want to select the 2nd one, you would do it as follows:
$("tbody").find("tr").each(function(){
$(this).find("td:eq(1)").html("changed")
};
Here is a Fiddle to play with. And here is the documentation of :eq().
Does this work, if you grab the data by an attribute selector?
var borgid = $(this).find("td[data-borgid]").data("borgid");
It could also be beneficial to avoid ":nth-child", shall you change your HTML later.
I'm really new in javascripting...(my webpage is based on jsp)
I'm trying to generate input box when option from select box is selected...
When user select any input from select box, it will send value to function init() and generate input boxes based on the value...
For example: if
<option value="IP,OS" name="sysl"><%=sysname%></option>
is selected..then it should generate something like
<tr>
<td> Enter IP:</td>
<td><input type="text" id="IP" name="IP"></td>
</tr>
<tr>
<td> Enter OS:</td>
<td><input type="text" id="OS" name="OS"></td>
</tr>
But my code does doesn't generate any...
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<title>Run Batch Script</title>
<script type="text/javascript">
function init() {
document.getElementById("bname").addEventListener("change", function(){
var value = document.getElementById("bname").value; // this gives you the selected value.
var split = value.split;
var splitsize = split.length;
for (var j=0; j<splitsize; j++){
var a = "<input type = 'text' name = '" + split[j] + "' id = '" + split[j] + "'>";
document.getElementById("inputBox").innerHTML = a;
}
// Your code to add the element that you need.
}
)};
</script>
<body>
<form action="./run?host=<%=host%>&envname=<%=envname%>" method="post" name="batchForm">
<table border="0">
<tr style="font-weight: bold; font-size: 16px;">
<td>System Name: </td>
</tr>
<tr>
<td>Select Batch : </td>
<td><select id="bname" name="bname" onclicke="init()">
<%
String src = "";
String[] temp;
String loc = root + "\\" + "Temp.txt";
int c;
int tempsize;
String param;
BufferedReader S = new BufferedReader(new FileReader(loc));
ArrayList<String> list = new ArrayList<String>();
while ((src = S.readLine()) != null){
c = 3;
param = "";
temp =src.split(":");
tempsize =temp.length;
list.add(temp[0]);
if ((tempsize >2)){
int i;
for (i=2; tempsize>i ; i++){
if((temp[i].equals("null"))){
param = "";
}
else if ((i ==2) && (temp[i] != "null")){
param = temp[i];
}
else if ((i > 2)){
param = param + "," + temp[i];
}
}
}
%>
<option value="<%=param%>" name="<%=temp[0]%>"><%=temp[0]%></option>
<%
}
BatchS.close();
%>
</select></td>
</tr>
<div id = "inputBox"></div>
What did I do wrong?
Thanks in advance!
There is some confusion about the event registration of your tag. As you said your are new to javascript, I think that it worth some explanation about event registration.
You have two ways to register some event in your HTML tag.
Using some onSomething attribute, for example:
<select onclick="myFunction()"/>
The other way, is to register the event handler using javascript:
document.getElementById("sysinfo").addEventListener("click", function(){...});
Both will work. However, in the first example the handler will be registered for you automatically when the page loads. The second way, the handler must be registered manually.
In your code you are trying to mix both.
You can either use the tag event registration, and the event is onchange (not onselect as pointed by David). OR you will have to call the init() function when the page loads. One way to do that is by putting the following code at the end of your HTML to register your event when page loads.
<script type="text/javascript">
init();
</script>
In summary I would do:
<script type="text/javascript">
function writeInputs() {
alert('writing inputs'); //helps checking if the handler is ok .. comment this when done
var value = document.getElementById("sysinfo").value; // this gives you the selected value.
var split = value.split;
var splitsize = split.length;
var code = '';
for (var j=0; j<splitsize; j++){
var a = "<input type = 'text' name = '" + split[j] + "' id = '" + split[j] + "'>";
code += a;
}
document.getElementById("inputBox").innerHTML = code;
}
</script>
<select id="sysinfo" name="sysname" onchange="writeInputs()">
The javascript is already corrected with a solution to the problem pointed by JB Nizet. I have not tested the code so there can be other problems