Hay guys, I'm doing some work where i have a large collection of forms. Seems these aren't 'posted' the traditional way (i.e using a submit button). I need a way to collect all the names and values of all form data when clicking a link (document.location is then used for redirects).
I want names to stay intact so that i can used a simple PHP script to work with the data.
any suggestions?
Might I suggest Serialize Form to JSON:
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
and then you can do:
var formArray = $("#myform").serializeObject();
$.fn.valuesArr = function()
{
var a = [];
jQuery.each(this, function(i, field){
a.push($.trim(field.value));
});
return a;
}
USE:
var myArr = $('input', $parentJQelem).valuesArr();
You could use something like my submit helper as a base
function submit(form) {
var form = $(form);
$.ajax(
{ data: $.param( form.serializeArray()),
dataType:'script',
type:'post',
url: form.attr("action")});
}
instead of a 'serializeArray()' i would use 'serialize()' and instead of posting it using ajax you could do whatever you want.
Sorry, dont have more time right now, but hopefully this snippet helps you.
cletus's answer is the best one in terms of efficency.
This is however another working solution that does not rely on JSON:
//this is my object I will fill my array with
function myObject(name, value)
{
this.name = name;
this.value = value;
}
var arr = $.map(
$('span'), function (item) {
var $item = $(item); //no need to $(item) 2 times
return new
myObject(
$item.attr("name"), //name field
$item.text() //value field
);
}
);
arr will be an array of myObject, each of them containing a name property and a value property.
Use your selector instead of $('span').
but all this functions dont work witch array names in inputs.
example -
this is correct for submit post form but when serialize i get
form[type[]]:2
this is not correct - i need - form[type][]:2
Related
Im using a MVC in PHP and I have this script created in my form page to validate three text boxes. When these three text boxes contain a value my php code in my controller asks Google Map Api for the closest directions based on the input of these three fields.
In my script I have the variable "direccion" which is what I need to pass to the controller using PHP but im not sure how to accomplish this.
Script Code (View):
jQuery(document).ready(function () {
var direccion="";
var flag = false;
jQuery(".validation").change(function () {
flag = true;
jQuery(".validation").each(function () {
if (jQuery(this).val().trim() == "") {
alert("false");
flag = false;
}
});
if (flag==true) {
var calle = jQuery("#ff_elem295").val();
var municipio = jQuery("#id_municipio option:selected").text();
var provincia = jQuery("#id_provincia option:selected").text();
direccion = calle +","+ municipio +","+ provincia;
direccion = direccion.replace(/\s/g,'+');
//alert(direccion);
}
});
jQuery.ajax({
url: "index.php?option=com_cstudomus&controller=saloninmobiliarios&task=calcularDistancias",
data : direccion,
dataType : 'html'
}).done(function(){
var data = data;
});
});
PHP Code (Controller):
function calcularDistancias(){
$valor = JRequest::getVar('direccion');
$url = 'http://maps.googleapis.com/maps/api/geocode/json?address='. $valor .'&sensor=false';
$data = file_get_contents($url);
$data_array = json_decode($data,true);
$lat = $data_array[results][0][geometry][location][lat];
$lng = $data_array[results][0][geometry][location][lng];
......
}
data property in the object passed to jQuery.ajax is an object.
data : { direccion: direccion }
Then you can access the value of direccion in your controller as a request parameter.
In the if condition put your ajax request like
if(flag == true) {
jQuery.ajax({
url: "index.php?option=com_cstudomus&controller=saloninmobiliarios&task=calcularDistancias",
data : {direction : direccion},
dataType : 'html'
}).done(function(){
var data = data;
});
}
In addition the retrieved data are missing in your code, don't forget to put data in done function :
.done(function(){
var data = data;
});
To
.done(function(data){
var data = data;
});
I have a little bit of a problem, I have a JavaScript with jQuery where I work with an Array I got from PHP, in the script I add some data to two new arrays and here comes my problem, how can I work with those two arrays in my PHP file? I need to save the data from the two new arrays in a database. In the PHP I have a form where I enter some data about a User. Does someone knows a easy way to send my data back to the PHP?
Some information about the script: I have a table with the names of schools, and a checkbox with the id of the school as a value. when i check or uncheck one of the checkboxes the script checks if it is a school already saved in the database for this specific user or if it's a new user.
<script>
var schools = [];
var oldschools = [];
var uncheckedschools = [];
oldschools = <?php echo json_encode($oldschoolids); ?>;
$(".checkbox").change(function() {
if(this.checked) {
var additem = $(this).val();
for (var i=0; i<oldschools.length; i++) {
if (additem == oldschools[i]) {
uncheckedschools = jQuery.grep(uncheckedschools, function(value) {
return value != additem;
});
}
}
schools.push(additem);
} else {
var removeitem = $(this).val();
for (var i=0; i<oldschools.length; i++) {
if (removeitem == oldschools[i]) {
uncheckedschools.push(removeitem);
}
}
schools = jQuery.grep(schools, function(value) {
return value != removeitem;
});
}
});
</script>
I hope someone can help me with this problem!
You'll need to use AJAX to send your updates back to your server. Using jQuery's ajax() method, it would looks something like this:
$.ajax({
url: 'path/to/serverside/file.php',
dataType: 'json',
data: {schools: schools},
success: function(dataFromServer) {
//after the save is successful, you can do something here
},
error: function(dataFromServer) {
//if there was an error handle it here
}
});
EDIT: As mentioned by a few commentors, you'll need to use json_decode on the server-side to decode the JSON Object you're sending back: http://php.net/manual/en/function.json-decode.php
I know this question has been asked before, but I wasn't able to find any answers that are up to date or functional (at least for my application).
My JQuery autocomplete box is using a mysql database as its source. I want the user to be able to type to get recommendations, but then is forced to select from the dropdown choices before they can submit the form.
My Javascript:
<script type="text/javascript">
$.widget( 'ui.autocomplete', $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
var that = this;
$.ui.autocomplete.currentItems = items;
$.each( items, function( index, item ) {
that._renderItemData( ul, item );
});
}
});
$.ui.autocomplete.currentItems = [];
$(function() {
$("#college").autocomplete({
source: "search.php",
minLength: 5
});
});
var inputs = {college: false};
$('#college').change(function(){
var id = this.id;
inputs[id] = false;
var length = $.ui.autocomplete.currentItems.length;
for(var i=0; i<length; i++){
if($(this).val() == $.ui.autocomplete.currentItems[i].value){
inputs[id] = true;
}
}
});
$('#submit').click(function(){
for(input in inputs){
if(inputs.hasOwnProperty(input) && inputs[input] == false){
alert('incorrect');
return false;
}
}
alert('correct');
$('#college_select_form').submit();
});
</script>
My form:
<form action="choose.php" method="post" id="college_select_form" name="college_select_form">
<input type="text" id="college" name="college" class="entry_field" value="Type your school" onclick="this.value='';" onfocus="this.select()" onblur="this.value=!this.value?'Type your school':this.value;" /><input type="submit" id="submit" name="submit" class="submitButton" value="Go" title="Click to select school" />
</form>
Search.php:
<?php
try {
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
$return_arr = array();
if ($conn)
{
$ac_term = "%".$_GET['term']."%";
$query = "SELECT * FROM college_list where name like :term";
$result = $conn->prepare($query);
$result->bindValue(":term",$ac_term);
$result->execute();
/* Retrieve and store in array the results of the query.*/
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
array_push($return_arr, array('label' => $row['name'], 'value' => $row['name']));
}
}
/* Free connection resources. */
//$conn = null;
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
?>
So what would be the best approach to doing this? The only solution I can think of is using PHP to verify that the textbox's value matches a value in the database, but I'm not sure how to implement that with my current code.
You should always check it in "choose.php" (server-side) since the user can disable the JavaScript and post whatever they want in the inputs of your form
$college = mysql_real_escape_string($_GET['college']);
if ($college != "" || $college != null || $college != -1)
{
//DO STUFF
}
NOTE: YOU SHOULD ALWAYS USE "mysql_real_escape_string" to prevent SQL Injection!
more info: http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php
So accordingly in search.php change the
$ac_term = "%".$_GET['term']."%";
to
$ac_term = "%". mysql_real_escape_string($_GET['term']) ."%";
You can also check the form before the user submit to just make it more user friendly (users don't want to wait couple of seconds for the page to gets refreshed with errors on it!)
so maybe something like this would help: Submit Event Listener for a form
function evtSubmit(e) {
// code
e.preventDefault();
// CHECK IT HERE!
};
var myform = document.myForm;
myform.setAttribute('action', 'javascript:evtSubmit();');
In my project i handled it by checking on focus-out , if the text entered in the autocomplete field actually matches my dropdown options.If not i will simply remove it.
change: function(event, ui) {
if (!ui.item) {
this.value = '';
}
}
See my full example here-Jquery auto comp example
it has an embeded fiddle,you can check the fiddle directly also
http://jsfiddle.net/9Agqm/3/light/
Add this code to your JavaScript before you instantiate your autocomplete object:
$.widget( 'ui.autocomplete', $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
var that = this;
$.ui.autocomplete.currentItems = items;
$.each( items, function( index, item ) {
that._renderItemData( ul, item );
});
}
});
$.ui.autocomplete.currentItems = [];
This will make it so whenever the menu appears, you have a list of current items the user can choose from stored in $.ui.autocomplete.currentItems. You can then use that to check against when you are submitting your form. Of course the way you implement this part is up to you depending on how dynamic your form is, but here is an example that requires hard-coding a list of input fields and making sure they all have ids.
//create an object that contains every input's id with a starting value of false
var inputs = {college: false};
//for each input, you will have a function that updates your 'inputs' object
//as long as all inputs have id's and they all are using autocomplete,
//the first line could be written as: $('input').change(function(){ and the
//function would only need to be written once. It is easier to maintain
//if you use seperate id's though like so:
$('#college').change(function(){
var id = this.id;
inputs[id] = false;
var length = $.ui.autocomplete.currentItems.length;
for(var i=0; i<length; i++){
if($(this).val() == $.ui.autocomplete.currentItems[i].value){
inputs[id] = true;
}
}
});
//when you submit, check that your inputs are all marked as true
$('#submit').click(function(){
for(input in inputs){
if(inputs.hasOwnProperty(input) && inputs[input] == false){
return false; //one or more input does not have correct value
}
}
//all inputs have a value generated from search.php
$('#myform').submit();
});
UPDATE
The only difference between our two examples (one that works and one that doesn't) is that you are binding other events to your input element, onclick and onblur. So by changing our listener from change to blur as well mostly fixes the problem. But it creates a new problem when the enter/return key is pressed to submit the form. So if we add a listener for that specific event then everything works out ok. Here is what the code looks like now:
var validateInfo = function(elem){
var id = elem.id;
inputs[id] = false;
var length = $.ui.autocomplete.currentItems.length;
for(var i=0; i<length; i++){
if($(elem).val() == $.ui.autocomplete.currentItems[i].value){
inputs[id] = true;
}
}
}
$('#college').on('blur', function(){
validateInfo(this);
}).on('keydown', function(e){
if(e.which == 13){ //Enter key pressed
validateInfo(this);
}
});
Add a hidden input element to your form:
<input type="hidden" name="selectedvalue" id="selectedvalue" />
Add a select event handler to your autocomplete, that copies the selected value to the hidden input:
$("#college").autocomplete({
source: "search.php",
minLength: 5,
select: function (event, ui) {
$('#selectedvalue').val(ui.item.value);
}
});
Then just ignore the auto-complete form input in posted data.
As this is javascript, your only concern should be if an item is selected from the autocomplete list. This can simply be done by setting a variable to true on select and false on change. That is enough to prevent regular users from continuing without selecting a school. To prevent abuse you need to check the value server side after posting. All normal user will pass that check.
If I understand the question correctly, this is something I have encountered before. Here is some code pretty much lifted straight out of another project. I have used a local datasource here but the project this is lifted from uses remote data so there won't be a difference:
var valueSelected = '';
$('#college').autocomplete({
source: ['collegeA', 'collegeB', 'collegeC']
}).on('autocompletechange autocompleteselect', function (event, ui) {
if (!ui.item) {
valueSelected = '';
} else {
$('#submit').prop('disabled', false);
valueSelected = ui.item.label;
}
}).on('propertychange input keyup cut paste', function () {
if ($(this).val() != valueSelected) {
valueSelected = '';
}
$('#submit').prop('disabled', !valueSelected);
});
This will programatically enable and disable the submit button depending on whether a value has been selected by the user.
Fiddle here
How can I send multiple values to be picked up like this using JSON?
foreach($_POST['listItem'] as $key => $values){
list($eventDate, $eventTitle) = $values;
}
At the moment the values are sent as follows. But this doesn't appear to work properly as it is only sending some of the string. I also can't figure out where/how to send the caltitle value.
This is sending me crazy. Any help would be great.
var txt = $("#listbox");
var caltitle = copiedEventObject.title
var dtstart = $.fullCalendar.formatDate(copiedEventObject.start, 'yyyyMMdd');
var txt = $('#listbox');
txt.append("<li class ='listItem'> " + dtstart + "</li>")
// remove the element from the "Draggable Events" list
$(this).remove();
}
});
$('#calendarform').submit(function(e) {
var form = $(this);
var listItems = $('.listItem');
listItems.each(function(index){ //For each event do this:
var listItem = $(this);
$("<input type='hidden'/>").val(listItem.text()).appendTo(form).attr('name', 'listItem[' + index + ']');
});
//Get text information from elements
});
EDIT:
(using JSON)
$('#calendarform').submit(function(e) {
var form = $(this);
var going_to_be_json = [];
list.each(function(i, item) {
going_to_be_json.push({
'id':'test',
'title': 'test'
});
});
$('#stuff').val( JSON.stringify(going_to_be_json) );
});
Prepare the data into an array of objects then convert that array to JSON using JSON.stringify() and set the hidden form value to said string (or use XHR to submit it to the server).
Here is a very limited example of how to prepare the data:
var going_to_be_json = [];
list.each(function(i, item) {
going_to_be_json.push({
'id':item.id,
'title': item.title,
'date': (new Date()).now()
});
});
hidden_form_element.val( JSON.stringify(going_to_be_json) );
and on the server
<?php
$json_data_string = $_POST['hidden_form_field_containing_json_data']; // sanitize however
$array_data = json_decode($json_data_string);
More can be ready about JSON (Javascript Object Notation) from json.org and the Tag Wiki (although the tag wiki just shows you more examples and links)
it seems you needed a little more direction. I was hoping you wouldn't just copy and paste what I had and you would read and attempt to understand what it is doing....
$('#calendarform').submit(function(e) {
var form = $(this),
listItems = $('.listItem'),
data = [],
hidden = $('<input />'); // create a hidden field for the form.
// or just select the hidden form element from the page
hidden[0].type = 'hidden'; // set the type
hidden[0].name = 'some_name_for_php_to_recognize'; // and name
listItems.each(function(i,el){
data.push({'index': i, 'text': $(el).text()});
});
hidden.val(JSON.stringify(data));
$(this).append(hidden); // not needed if the hidden element is already in the DOM
});
send it with jQuery Post or Get method and fetch it by php you can send multiple values
use $.post or $.get
Here is a part of my view(a javascript method that is executed on a button click):
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
var moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
var editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
var jEditors = str3.split(',');
}
Here is the controller method i need to call using the 3 arrays from the javascript(moderators, editors,jEditors):
function insertPos($moderators,$editors,$jEditors){
$account = new Account();
$account->insertPos($moderators,$editors,$jEditors);
}
I need to know how to execute the controller method insertPos($moderators,$editors,$jEditors) using the 3 arrays in the javascript method...
I used this to send the arrays in the javascript like you told me:
$.post('http://localhost/cakephp/Accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in the controller i try to access my arrays like this:
public function insertPos() {
if (!empty($this->request->data)){
print_r($this->request->data);
$moderators = $this->request->data['moderators'];
$editors = $this->request->data['editors'];
$jEditors = $this->request->data['jEditors'];
$account = new Account();
$account->assignPos($moderators,$editors,$jEditors);
}
}
the part inside the if(!empty($this->request->data)) is never executed so that means the arrays have not been sent to the controller.... where is the problem?
thank you....
It looks like you're trying to access a controller class directly. This is not how CakePHP works. You have to go through the dispatch process. Please read: http://book.cakephp.org/2.0/en/getting-started/a-typical-cakephp-request.html
That said, the way you would POST to a CakePHP url is thusly:
// POST to the AccountsController's insertPos method
$.post('/accounts/insertPos');
To pass data, pass it in the data option as specified with jQuery, prefixed with 'data', like data[moderators] so it ends up in Cake's data variable.
$.post('/accounts/insertPos', {
data: {
'data[moderators]': moderators,
'data[editors]': editors,
'data[jEditors]': jEditors
}
});
The data will now end up in $this->request->data in Cake.
Looking at your insertPost() method, though, you are passing them simply as parameters, so instead you would write your ajax like so
// POST is unnecessary here, since you aren't POSTing data
$.get('/accounts/insertPos/'+moderators+'/'+editors+'/'+jEditors);
You will probably need to stringify your JavaScript arrays and use json_decode in your inserPos method to convert them to PHP objects, since you can't just pass arrays from JavaScript to PHP.
don't use array notation in data parameter; just use keys like this:
$.post('/accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in your controller access it as $this->request->data[key] not $this->request->data->data[key]
in the view replace your assign function with the following:
var moderators, editors, jEditors;
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
jEditors = str3.split(',');
}
Good luck