I'm working on a project that involves returning the id of the checkboxes chosen as well as the text in the corresponding textarea fields for those chosen checkboxes. The data is dynamically displayed and so far my jquery pull of both the checkboxes and textareas work:
var noteList = $("textarea[name='revokeNotes']").map(function(){
return this.value;
}).get().join();
var revokeList = $("input[name='revoke']:checked").map(function(){
return this.id;
}).get().join();
but I'm getting back all of the notes fields and I'm uncertain how to best iterate through them to find the proper notes as their ids aren't sequential but rather based on their id in the table they are being pulled from. The last version of the display code is below:
<td><textarea name=\"revokeNotes\" id=\"".$v["id"]."\" cols=\"30\"rows=\"3\">".$v["notes"]."</textarea></td>
<td><input type=\"checkbox\" id=\"".$v["id"]."\" name=\"revoke\" value=\"".$v["id"]."\" /></td>
Is there a way to reach my goal from this state or should I be using another jquery function, similar to .map()? I thought about using the id field from the checkboxes to iterate through the selected notes and pushing them into an array but I'm not sure 1) if that will work and 2) how to do that.
I need the data back in some form either an array or something I can explode on in php to create an array as I'm passing one value in ajax as there is no set maximum or minimum number of rows that will be displayed per user. Map was working until I threw some commas at it. Extra points for that.
var noteList = $.map(
$("textarea[name='revokeNotes']").filter(function() {
return $(this).closest('td')
.next('td')
.find('input[type="checkbox"]')
.is(':checked');
}), function(el) {
return el.value;
}).join();
adeneo's answer is great, I'd just propose the following improvements:
If possible use class selectors (like '.revoke-notes-area') since those are faster than DOM + attr selectors
Assuming this is a table and there is one textarea checkbox combo per row, you can traverse the tree to the closest <tr> a decouple the JS from depending that the checkbox comes after the text area in the DOM.
var filterMethod = function() {
$(this).closest('tr').find('.revoke-checkbox').is(':checked');
};
var mapMethod = function(el) {
return el.value;
};
var nodeList = $.map($('.revoke-notes-area').filter(filterMethod), mapMethod);
There's no reason you cannot or should not put the filter and map methods inline, I just split them out into variables so it's easier to read here.
You can check out my codepen here: http://codepen.io/aaron/pen/eIpby.
Related
I'm sorry I haven't included "my attempt" as such with this one, I'm useless with jquery so need some advice!!
I would like to change the value of a second selctor based on the results of the first.
I have a database of builders and regions with the headers builder_name and builder_region. The list ends up looking like this ...
builder_1 region_1
builder_1 region_2
builder_2 region_1
builder_3 region_1
builder_3 region_2
builder_3 region_3
(You get the idea)
I'm using the following in the form I've built to get a list of the builders for the first select box ...
echo '<select class= "ml-select" name="gen_builder">';
echo '<option value=" ">Select Builder</option>';
while($row = mysql_fetch_array($rsBUILDER)) {
if($linebreak !== $row['builder_name']) {
echo '<option value="'.$row['builder_name'].'">'.$row['builder_name'].'</option>';
}
else {echo "";}
$linebreak = $row['builder_name'];
}
echo '</select>';
The $linebreak is to get rid of the duplicate builder names from the list, which works a treat.
What I would like to achieve is a second selector that selects the regions available, dependant upon the builder that has been selected in the first option. I hope this makes sense????
The second query needs to look at the builder selected in the first selector and filter out just the regions that are in rows with the builder name form selector one.
Please do say if you need further information, I'm not great at explaining myself.
As you said you don't have experience with jQuery or Ajax, I'll post my answer with as many comments as possible. I will assume that you have two select dropdowns in your page.
The first one contains the builders, so it will have id="builders".
The second one contains the regions, so it will have id="regions".
From what I understand, the first select will be exactly the one you posted in your question, generated server-side (by PHP). I only ask that you please make a slight change on it, making each option value be equal to the builder's database ID, and not its name (unless the builder's primary key is their name, and not an ID). This will make no difference for the final user but will be important for our jQuery solution. The second one will be empty, as the idea is to fill it dynamically with the regions related to the builder selected in the first dropdown.
Now let's get to the jQuery code:
//Everything that goes below this first line will be ready as soon as the page is fully loaded
$(document).ready(function() {
//The following code defines an event. More precisely, we are defining that the code inside it will run every time our select with id "builders" has its value changed
$('#builders').change(function() {
//$(this) is our builders select. $(this).val() contains the selected value, which is the ID of our selected builder
var currentValue = $(this).val();
//Now, this is our Ajax command that will invoke a script called get_regions.php, which will receive the builder's ID in $_GET['builder_id'] and you can use to query your database looking for all regions related to this builder. Make sure to create an array with the returned regions. Your get_regions.php's last line should be echo json_encode($regions);
$.get("get_regions.php", {'builder_id': currentValue}, function(data) {
//Inside this function is the code that will run when we receive the response from our PHP script. It contains a JSON encoded list of regions, so first of all we need to parse this JSON
var regions = $.parseJSON(data);
//Before filling our second select dropdown with the regions, let's remove all options it already contains, if any
$('#regions').empty();
//Now, all there is left is to loop over the regions, adding each as an option of the regions dropdown. I'll do it the universal way
for (var i = 0; i < regions.length; i++) {
var regionOption = '<option value="'+regions[i]['region_name']+'">';
regionOption += regions[i]['region_name'];
regionOption += '</option>';
$('#regions').append(regionOption);
}
});
});
});
Despite any syntax errors (can't test the code from here) this should do the trick. Hope the comments were clear enough for you to understand how things work in jQuery.
I had implemented multiple checkbox filtering for a job portal using jQuery where in I was calling a function every time a checkbox is checked and that function contained an ajax call which would send the request with the checked values and I would do the querying of database and return the result.
But one of the developers I meet told me you should not hit the database continuously for filtering, it should be done client-side.
He also suggested to use AngularJS or Knockout(js) for the purpose, as they work on content, whereas jQuery works on DOM elements.
But if it has to be done client-side, all of the data must be loaded at once during the first visit to the page, which in turn would slow down the page.
And I cannot use class on each element and show/hide them based on the checkbox ID or value something like that, because there are a lot of checkboxes, which I think will be hectic to handle.
How to achieve the desirable result with good performance?
I'm a Newbie to jQuery, so if I have gone wrong anywhere bear with me.
Below is the sample way in which I have actually done:
HTML:
<input type="checkbox" name="location[]" value="Bangalore" onclick="loadresult()">Bangalore
JS:
function loadresult() {
location array value accessed and passed to ajaxcall
//ajax call to processresult.php
Displaying the DB returned Data
}
PHP (processresult.php):
<?php
//dbconnection + querying db and returning result
?>
There is significant difference. Angular is a framework and jQuery is a library.
With jQuery it much simpler to modify DOM elements deal with events and do some more cool stuff. But you define how you deal with data on your own. You can easily move your data to Js object or array of objects and render this data to your DOM tree.
For example:
//let's presume that you are searching something
var someUsers = [{id: 1,name:'User 1'},{id: 2,name:'User 2'},{id: 1,name:'User 3'}];
var usersTemplate = _.template("<h1>User name: <%= user.name %></h1>");
var $container = $('#someRenderContainer');
someInputFeild.on('keypress', function(){
var searchText = someInputFeild.text();
var foundUsers = someUsers.filter(function(item, index){
item.name.indexOf(searchText) !== -1
});
render($container,foundUsers);
})
function render($container,users){
users.forEach(function(item){
$container.append(usersTemplate(item));
})
}
Here is simple example where you can see that your manipulate with data in the memory but not in DOM. Similar things you can do with your checkboxes.
I would just make one ajax request in the beginning, fill the page with data, marking every row with class name
jQuery.each(d, function(i,data) {
$("table.content").append("<tr class=\""+data.city+"\"><td>" + data.tag + "</td><td>" + data.city + "</td><td>" + data.num + "</td><td>" + data.state + "</td></tr>");
});
and use checkboxes to hide and show marked rows using jQuery hide(), show() methods.
Rows can have multiple classes meaning filtered by multiple columns, but logic will get more complicated.
see example http://jsfiddle.net/elshnkhll/czdongkp/
I would use cache technique to improve my performance.
We can't load our full record on a single page. It will slow down the main page loading.
But we can save loaded data in a variable with some key combination for different filter and page no..
eg. if we are loading data fir index page with no filter, the my key will be index and my variable will be like var cachevar = {"index":{1:"<my response>"}}, here "1" is page number
And if data is using filter, then my variable index key will be combination of filter ids saperated by '-'.
eg var cachevar = {"index":{1:"<my response>"}, "index-2-5-3":{1:"my response"}}
If user request a page, I just have to check if that page is available in cache or no, if it's available in cache variable, then show it, else request it from server.
A bit of a random exercise but I want to take content from an existing table and create a new table based on the entries taken.
In the image above, the table on the left is what I have to work with already. The blue table on the right is what I want to create; using the data from the table on the left.
Can this be done with jQuery or some basic PHP?
If you're wondering why I'm doing this its because I don't have access to the SQL database and I want to use Google Charts API to display total number of user registrations for each month.
As always, your help is MUCH appreciated.
Using JQuery it can be done in this way
//initialize monthArray
var monthArr = [{month:'April', occ:0}, {month:'May', occ:0},{month:'June', occ:0}];
//read occurrences for MonthNames in your existing table
$.each(monthArr, function(n,i){
var _occ = $("td:contains('"+monthArr[n].month+"')").size();
monthArr[n].occ = _occ;
});
// create new table and show the values
$.each(monthArr, function(index, value) {
//alert(value.occ+ ': ' + value.month);
$('#inTable').append('<tr><td>'+value.month+'</td><td>'+value.occ+'</td></tr>');
});
Here is fiddle: http://jsfiddle.net/A3WeJ/38/
Note: Table look and feel formatting has not been done in this solution
The question of whether or not you wish to use jQuery or PHP depends on whether the content of these tables is likely to change after the page has loaded. If the page will not change, you should use PHP.
Assuming the table is produced using a while or foreach loop, you can simply set up counts for each option that you have in the table. Within the loop, if you check what is in this column and add to an appropriate arbitrary count, you can count how many are in each.
It would probably be good to check what the contents is, and if it's already in your array.
Hope that provides some initial help to the thinking behind this question!
You may try this (You didn't provide more information, so just may be an idea)
HTML The id maintable could be changed with another id/class or just table
<table id="maintable">
<thead><th>Name</th><th>Join Month</th><th>Join Year</th></thead>
<tbody>
<tr><td>Joe Blogs</td><td>April</td><td>2012</td></tr>
<tr><td>Mr. X</td><td>April</td><td>2012</td></tr>
<tr><td>Andrew Xmen</td><td>April</td><td>2012</td></tr>
<tr><td>Matt Bblogs</td><td>may</td><td>2012</td></tr>
<tr><td>Malcom McGuiness</td><td>June</td><td>2012</td></tr>
<tr><td>Friday Needavodka</td><td>June</td><td>2012</td></tr>
</tbody>
</table>
<div id="myTblDiv"></div>
JS
$(function(){
var rows={};
$('table#maintable tbody tr').each(function(){
var item=$('td:eq(1)', $(this));
if(rows.hasOwnProperty(item.text()))
rows[item.text()]=parseInt(rows[item.text()])+1;
else rows[item.text()]=1;
});
var myTable=$('<table />', {'id':'myNewtable', 'class':'table table-striped'});
var th=$('<thead><th>Total</th><th>Month</th></thead>');
var tbody=$('<tbody></tbody>');
myTable.append(th).append(tbody);
$.each(rows, function(k, v){
var row=$('<tr><td>'+v+'</td><td>'+k+'</td></tr>');
myTable.find('tbody').append(row);
});
$('div#myTblDiv').append(myTable);
});
DEMO or Different Style.
Notice, I've used an id (maintable) for the table generated by google, in this case you have to change the id or class (if it has any) or even you can just use table without any id or class name but make sure there is only one table when you are using only $('table'), also if you can wrap the table within a parent div then you can use $('div#parentDivId table').
Basically I am creating a number of rectangles using jQuery and adding these to the DOM e.g.
var divElement = jQuery('<div/>').attr({
'class': 'ui-widget-content resizable'
});
I am then allowing the user to fill out input fields for the selected rectangle e.g. name, width, height. This data is currently being added to each element via .data method.
Once the user has created all their elements along with their associated meta data, I would like them to submit the page so I can do some server side scripting in PHP.
Just wondering what the best way is to submit this data - as I understand it, I could dynamically create form elements or use the jQuery.post method.
Please can anyone advise on the best method (perhaps a different one altogether) and any tips on how to set this up e.g. using [] brackets in the name of each element to create arrays etc..
A good way will be to construct an object, or array, and fill it with all the data you wish to save. and then send it to your server using $.post() for storage.
var data = new Array;
data['height'] = 100;
data['width'] = 200;
$.post('save.php', data, function(result){
// test if successful and carry on
});
source: http://api.jquery.com/jQuery.post/
I want to use the autocomplete plugin for jQuery to populate not one, but two fields when selecting one of the autocomplete values - the name of a band is entered in the #band input field, but the band url (if exists) should also automatically be added to the #url input field when selecting the band name.
Right now I simply have an un-pretty list in an external php file from which the autocompleter takes it's values:
$bands_sql = "SELECT bands.name, bands.url
FROM bands
ORDER BY name";
$bands_result = mysql_query($bands_sql) or print (mysql_error());
while ($bands_row = mysql_fetch_array($bands_result)) {
$band_name = $bands_row['name'];
$band_url = $bands_row['url'];
echo $band_name."\n"; #needs to be replaced with an array that holds name and url
}
My autocomplete function looks very basic atm, but as I'm an absolute beginner when it comes to jQuery (and also clueless when it comes to PHP arrays), I have no idea how to tell it to populate two fields and not one.
$(document).ready(function() {
$("#band").autocomplete('/autocomplete-bands.php');
});
Is that even possible?!
sure check use result hadler so you can then do what you want once a choice has been made
I don't know about the particular plug-in you are using, but I would use the autocomplete widget for jQuery UI instead of a third party plug-in.
Here is an example of what you are looking for:
$("#band").autocomplete('/autocomplete-bands.php').result(function(event, data, formatted) {
if (data)
$('#url').(data['url']);
else {
// no data returned from autocomplete URL
}
});
I don't know much about php, but whatever the format of your data that is returned should be put where the data['url'] is currently in order to populate the #url input.