AjaxSubmit overwrite form field before send - ajax

I would like to overwrite the value of the "password" field before submiting a form on Jquery using AjaxSubmit function.
I know I can just update the value on the input field but, I don't want the user to see this transformation. In other words, I just want to send a custom value to the password field and keep the current value on the screen...
How could I do that?
My current code:
var loginoptions = {
success: mySuccessFuction,
dataType: 'json'
}
$('#My_login_form').submit(function(e) {
e.preventDefault();
var pass=$("#My_login_form_password").val();
if (pass.length>0){
loginoptions.data={
password: ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)))
}
$("#My_login_form").ajaxSubmit(loginoptions);
delete loginoptions.data;
});
The problem with this code is that it is sending a "password" POST variable with the form field value and, a duplicated one with the value I set on "loginoptions.data".

Building off of Cristiano's answer, I was able to get this to work. If you use :beforeSubmit(), the changed value doesn't post, but if you use the :beforeSerialize(), it posts the changed value.
$('#ff').ajaxForm({
beforeSerialize:function(jqForm, options){
var serializedForm = decodeURIComponent(jqForm.serialize());
options.data = serializedForm.deserializeToObject();
options.data.tPassword = MD5($("#tPassword").val())
},
success:function(data){
// do stuff
}
});

If you want to do it anyhow then I think you can use callback function beforeSubmit: function(contentArray, $form, options){}
beforeSubmit: function(contentArray, $form, options){
for(var i=0; i<contentArray.length; i++){
if(contentArray[i].name == "password") {
contentArray[i].value = ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)))
}
}
}

It seems that ajaxSubmit uses the serialize() function of jquery on the form and then, adds the extra data serialized too. So, if I have a field named "password" with the value "1234" and then try to change that to "abcd", using "loginoptions.data.password", it will serialize everything and put the "options.data" like this:
"password=1234&field_2=value_2&password=abcd"
After many tries, I gave up on using ajaxSubmit function and decided to use ajax function to submit the form:
var the_form=$('form#My_login_form');
loginoptions.url=the_form.attr("action");
loginoptions.type=the_form.attr("method");
var serializedForm=decodeURIComponent(the_form.serialize());
loginoptions.data=serializedForm.deserializeToObject();
var pass=$("#My_login_form_password").val();
if (pass.length>0){
loginoptions.data.password= ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)));
}
$.ajax(loginoptions);
Here is the deserializeToObject() function:
function deserializeToObject (){
var result = {};
this.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { result[$1] = $3; }
)
return result;
}
String.prototype.deserializeToObject = deserializeToObject;

Related

Laravel Search Array of Values

In my user registration workflow, I ask the user to select a pre-defined list of classifications (which I use a series of checkboxes for). Currently, I update my model with those values (or a blank value if the box isn't checked) when they move to the next step. These are not currently structured as an array, rather as a separate and distinct checkbox.
My 2 questions are as follows:
1) I read that if I save the checkboxes as an array I won't be able to easily search the database for users with a particular classification.
2) If that's true, I'm fine with my current structure, but I need to properly validate (server-side) that at least one of the checkboxes is selected otherwise provide an error. I have tried the following, but it doesn't return anything and the database record is created with nothing in each column.
if ($request->all() === "")
{
return Request::json('you must select one');
}
Database Table Migration:
Schema::create('user_type', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('games');
$table->string('art');
$table->string('music');
$table->string('building_stuff');
$table->string('educational');
$table->timestamps();
});
Javascript: (I submit as AJAX)
$('.modal-type-btn').click(function(e){
e.preventDefault();
if($('.checkbox-games').is(':checked'))
{
var games = "games";
} else {
var games = "";
}
if($('.checkbox-art').is(':checked'))
{
var art = "art";
} else {
var art = "";
}
if($('.checkbox-music').is(':checked'))
{
var music = music;
} else {
var music = "";
}
if($('.checkbox-building-stuff').is(':checked'))
{
var buildingStuff = "buildingstuff";
} else {
var buildingStuff = "";
}
if($('.checkbox-educational').is(':checked'))
{
var educational = "educational";
} else {
var educational = "";
}
$.ajax({
type: "POST",
url: "/profile/setup/1",
data: {games:games, art:art, music:music, buildingStuff:buildingStuff, educational:educational},
error: function(data){
console.log(data);
},
success: function(data){
console.log(data);
}
});
Thanks!
So, firstly you're much better of using them as an array and doing something like:
html:
<input type="checkbox" name="options[games]" value="1" />
that way, you can just get the form data and pass that into your $.ajax call:
...
data: $('form').serialize(),
....
and then in your controller, checking that the length of options is at least one:
$options = Input::get('options');
if(count($options) > 0){ ... }
You'll also probably want to define a list of "allowed" options and then use that to build your query:
private $_allowed_options = array('education', 'buildingStuff' ...);
public function update()
{
$options = Input::get('options');
foreach($this->_allowed_options as $allowed_options){
if(array_key_exists($allowed_option, $option)){
// add this option to our sql to add it to our user
// as they have selected it
}else{
// the user didn't select this one, so add it to be removed
// from the users
}
}
}

sending data from controller to model

I have the following code on my site which sending data to Ajax and works normal. It is about add to cart.
public function adding()
{
$id_lap=$this->input->post('id_lap');
$num_items=$this->input->post('num_items');
$price=$this->input->post('price');
if($id_lap !='')
{
$this->session->set_userdata('num_items',$num_items);
$this->session->set_userdata('price_new',$price);
$response=array(
'status'=>1,
'num_items'=>$num_items,
'price_new'=>$price
);
} else {
$response=array(
'status'=>0
);
}
echo json_encode($response);
}
When I want to send data to model also where I want to write data into database along with IP adress which I will collect with model. When I add new row anywhere my Ajax crashed. Part of code which I want to add is:
$this->users_mod->AddSesija($id_lap,$price);
And Ajax code which I am using is :
function Addtocart(id,prices)
{
var id_lap=id;
var ajaxURL= BASE_URL +'home/adding';
var num_items = parseInt($('#num_items').html()) + 1;
var price = parseInt($('#price_b').html());
var price_new = price + prices;
/*console.log(id_lap +' '+num_items+' '+price_new);
$('#num_items').html(num_items);
$('#price_b').html(price_new); */
$.ajax({
url:ajaxURL,
type:'POST',
data:{'id_lap':id_lap,'num_items':num_items,'price':price_new},
success:function(response)
{
var parsed = JSON.parse(response);
if(parsed.status ==1)
{
$('#num_items').html(parsed.num_items);
$('#price_b').html(parsed.price_new);
}
}
}
)
}
I am agree with Vladimir Glisovic in concept. we know that for adding or inserting group of data we should bind them into an array.
Sample:
$data=array( 'ip_adress'=>$ip_adress, 'id_lap'=>$id_lap, 'cena'=>$price );
N.b: get IP address from PHP code keep in $ip_address.
Then pass the data to model with the CI syntax.
Model calling in Controller:
$this->users_mod->AddSesija($data);
Now write the inserting code in the model file as
public function AddSesija($data){
insertion code here.....
}
Hope it will help you.
Thanks!
Amadercode

How to access object data posted by ajax in codeigniter

I am trying to access an object with form data sent to my controller. However, when I try to access objects I get values of null or 0. I used two methods, the first by serializing and the second by storing names and values in one object. (the code below sends/posts serialized)
Here is my JS...
$("#createUser").click(function() {
//store input values
var inputs = $('#newUserForm :input');
var input = $('#newUserForm :input').serializeArray();
console.log(input);
//if I want just the values in one object
var values = {};
$(inputs).each(function() {
values[this.name] = $(this).val();
});
console.log(values);
if(LiveValidation.massValidate( validObj )){
$.post('./adminPanel/createUser', function(input){
alert('Load was performed.');
//test confirmation box
$("#msgbox").html("Grrrrreat");
//drop down confirmation
$("#msgbox").slideDown();
});
} else {
//test fail box
$("#failbox").html("Fail");
$("#failbox").slideDown();
}
});
In the controller side I try to access data the following way...
$this->input->post("firstName")
where firstName is the name of the field.
Below is an image of the objects passed.
Top being serialized array and the bottom a single object with all the names and values of form...
If you're using jQuery, you can use jQuery's built in serialize/query string functions to get the data from a form: http://api.jquery.com/serialize/
In your case:
var data = $('#newUserForm').serialize(); // is a string like "firstName=jon"

How to use Zend Framework Form Hash (token) with AJAX

I have included Zend_Form_Element_Hash into a form multiplecheckbox form. I have jQuery set to fire off an AJAX request when a checkbox is clicked, I pass the token with this AJAX request. The first AJAX request works great, but the subsequent ones fail.
I suspect it may be once the token has been validated it is then removed from the session (hop = 1).
What would be your plan of attack for securing a form with Zend Framework Hash yet using AJAX to complete some of these requests?
I finally abandoned using Zend_Form_Element_Hash and just created a token manually, registered it with Zend_Session and then checked it upon submission.
form.php
$myNamespace = new Zend_Session_Namespace('authtoken');
$myNamespace->setExpirationSeconds(900);
$myNamespace->authtoken = $hash = md5(uniqid(rand(),1));
$auth = new Zend_Form_Element_Hidden('authtoken');
$auth->setValue($hash)
->setRequired('true')
->removeDecorator('HtmlTag')
->removeDecorator('Label');
controller.php
$mysession = new Zend_Session_Namespace('authtoken');
$hash = $mysession->authtoken;
if($hash == $data['authtoken']){
print "success";
} else {
print "you fail";
}
This seems to work and still keeps things relatively sane and secure. I'd still rather use the Hash element, but I can't seem to make it work with AJAX.
Thanks all.
That's how to handled hash field in ajax form :
class AuthController extends Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('index', 'json')
->initContext();
}
public function loginAction()
{
$form = new Application_Form_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
// some code ..
} else {
// some code ..
// Regenerate the hash and assign to the view
$reservationForm->hash->initCsrfToken();
$this->view->hash = $reservationForm->hash->getValue();
}
}
$this->view->form = $form;
}
}
And then in your view script ..
<? $this->dojo()->enable()
->requireModule('dojox.json.query')
->onLoadCaptureStart() ?>
function() {
var form = dojo.byId("login_form")
dojo.connect(form, "onsubmit", function(event) {
dojo.stopEvent(event);
var xhrArgs = {
form: this,
handleAs: "json",
load: function(data) {
// assign the new hash to the field
dojo.byId("hash").value = dojox.json.query("$.hash", data);
// some code ..
},
error: function(error) {
// some code ..
}
}
var deferred = dojo.xhrPost(xhrArgs);
});
}
<? $this->dojo()->onLoadCaptureEnd() ?>
Hope it's not too late :D
There is a solution:
Create, besides the form that will contain the data, a form without elements. From the controller you instantiate the two forms. Also in the controller, you add the element hash to the empty form. Both forms should be sent to the vision. Then, in the condition "if ($ request-> isXmlHttpRequest ())" in the controller you render the empty form. Then, you take the hash value with the method "getValue ()". This value must be sent in response by Ajax and then use JavaScript to replace the hash value that is already obsolete. The option to create an empty form for the hash is to avoid problems with other elements such as captcha that would have its id generated again if the form were rendered, and would also need to have the new information replaced. The validation will be done separately because there are two distinct forms. Later you can reuse the hash (empty) form whenever you want. The following are examples of the code.
//In the controller, after instantiating the empty form you add the Hash element to it:
$hash = new Zend_Form_Element_Hash('no_csrf_foo');
$hash_form->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
//...
//Also in the controller, within the condition "if ($request->isXmlHttpRequest())" you render the form (this will renew the session for the next attempt to send the form) and get the new id value:
$hash_form->render($this->view);
$hash_value['hash'] = $hash_form->getElement('no_csrf_foo')->getValue();//The value must be added to the ajax response in JSON, for example. One can use the methods Zend_Json::decode($response) and Zend_Json::encode($array) for conversions between PHP array and JSON.
//---------------------------------------
//In JavaScript, the Ajax response function:
document.getElementById("no_csrf_foo").value = data.hash;//Retrieves the hash value from the Json response and set it to the hash input.
Leo
Form hashes are great in principle and a bit of a nightmare in practice. I think the best way to handle this is to return the new hash with the response when you make a request, and update the form markup or store in memory for your javascript as appropriate.
The new hash may be available from the form object, or you can read it from the session.
You hinted at the right answer in your question: increase the hop count.
There was specific mention of this in the ZF manual online, but they updated their manuals and now i can't find it (grin)- otherwise i would have posted the link for you.
If you want to use form validator in ajax side use following code :
Myform.php
class Application_Form_Myform extends Zend_Form
{
# init function & ...
public function generateform($nohash = false)
{
# Some elements
if(!$nohash)
{
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
$my_hash = new Zend_Form_Element_Hash ( 'my_hash' );
$this->addElement ( $my_hash , 'my_hash');
$temp_csrf->hash = $my_hash->getHash();
}
# Some other elements
}
}
AjaxController.php
class AjaxController extends Zend_Controller_Action
{
// init ...
public function validateAction()
{
# ...
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
if($temp_csrf->hash == $params['received_hash_from_client'])
{
$Myform = new Application_Form_Myform();
$Myform->generateform(true);
if($AF_Bill->isValid($params))
{
# Form data is valid
}else{
# Form invalid
}
}else{
# Received hash from client is not valid
}
# ...
}
}

dojo.xhrPost and Zend Framework action, no POST data, not using a form

I'm trying to send some data via dojo.xhrPost to an Zend Controller Action. I can see the data being sent in Firebug console. However, when inspecting the post data, the array is empty.
I'm not sure if it is possible to send an arbitrary string of data via dojo.xhrPost without using a form. This is probably a very n00b mistake. In any case, I'll post my code here and see what you all think.
In my layout script I have:
<?php
$sizeurl = $this->baseUrl() . '/account/uisize';
?>
function resizeText(multiplier)
{
if (document.body.style.fontSize == "")
{
document.body.style.fontSize = "1.0em";
}
document.body.style.fontSize = parseFloat(document.body.style.fontSize) + (multiplier * 0.1) + "em";
var size = document.body.style.fontSize;
var xhrArgs = {
url: "<?= $sizeurl; ?>",
postData: size,
handleAs: "text"
}
dojo.xhrPost(xhrArgs);
}
Then my action is:
public function uisizeAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
print_r($_POST);
$request = $this->getRequest();
if ($request->isXmlHttpRequest())
{
$postdata = $request->getPost();
print_r($postdata);
if ($postdata)
{
$user = new Application_Model_DbTable_User();
$user->updateSize($postdata);
}
}
}
I'm pretty sure that post data from a form is an array with the form elements' names as the keys. When looking at the dojo.xhrPost examples on the dojo campus web site (http://docs.dojocampus.org/dojo/xhrPost second one to be precise), it looks as if I can just send a string of data. How do I access this data from a Zend Controller Action?
I'm using ZF 1.10 and Dojo 1.4.2
Thanks for your help!
PS
I'd try to ask on one of the related questions, but I cannot seem to comment.
After reading about http methods here:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
I figured that I need to encode the data sent in a way that will be converted to an array by PHP. So here is the new bit of javascript:
function resizeText(multiplier)
{
if (document.body.style.fontSize == "")
{
document.body.style.fontSize = "1.0em";
}
document.body.style.fontSize = parseFloat(document.body.style.fontSize) + (multiplier * 0.1) + "em";
var rawdata = "uisize="+document.body.style.fontSize;
var xhrArgs = {
url: "<?= $sizeurl; ?>",
postData: rawdata,
handleAs: "text"
}
//Call the asynchronous xhrPost
dojo.xhrPost(xhrArgs);
}
The difference is I am now specifying a key pair and sending that. When using AJAX that could make forms overkill. So now my UI is resized and the size is stored with the user's profile. So the next page they request will use the size they set. Cool.

Resources