I have a question about using a zend form in a twitter bootstrap modal. This is what I have:
In my Controller:
public function accountAction() {
$form = new Form_CancelAccount();
$this->view->form = $form;
// Some executions and view params for the view, ex:
/*if ($user->getRecurlyId() && NameSpace_Feature_Access_RoleHelper::hasAccess('show_billing')) {
try {
$account = Recurly_Account::get($user->getRecurlyId());
$this->view->token = $account->hosted_login_token;
$this->view->show_billing = true;
} catch (Recurly_NotFoundError $e) {
$this->view->show_billing = false;
}
} else {
$this->view->show_billing = false;
}*/
if ($this->getRequest()->isPost() && $form->isValid($_POST)) {
$data = $form->getValues();
var_dump($data);
} else {
var_dump("it didn't work!");
}
}
My CancelAccount Form:
<?php
class Form_CancelAccount extends NameSpace_Form_Base
{
public function __construct($options = null) {
parent::__construct($options);
$this->setName('cancelaccount');
$element = new Zend_Form_Element_Radio('reason');
$element->addMultiOptions(array(
'It is really bad!' => 'bad',
'No time for it!' => 'notime',
'Other option:' => 'otheroption'
))->setDecorators(array(array('ViewScript', array('viewScript' => 'user/radio.phtml'))));
$this->addElement($element);
$this->addElement('text', 'otheroption', array(
'attribs' => array(
'class' => 'input-block-level otheroption',
'size' => 30,
'placeholder' => 'Other option'
),
'decorators' => $this->elementDecoratorsNoTag
));
}
}
In my View:
// Some data sent from the controller
<h4>Delete account</h4>
<p>Deleting of your account implies your account and the related data will be deleted. Please note that this is not reversible.</p>
<button type="button" data-target="#cancelModal" data-toggle="modal" class="btn btn-primary">Delete account</button>
<div class="modal hide fade" id="cancelModal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<?php echo $this->form; ?>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-default" value="OK" form="cancelaccount">
<a id="cancel" class="btn btn-default close" data-dismiss="modal">Cancel</a>
</div>
But I always get the output 'it didn't work!' from the var_dump when the form isn't valid ... . What's the best way to do this? And how does it comes it's always not valid?
UPDATE:
When I leave out the "&& $form->isValid($_POST)" in my if statement I come in the statement, but my var_dump shows this:
array (size=2)
'reason' => null
'otheroption' => null
My response:
The problem is that my radiobuttons aren't valid ... How can I fix this?
The problem where my radiobuttons. Change the radiobuttons in my form to:
$this->addElement('radio', 'reason', array(
'label'=>'Reason:',
'multiOptions'=>array(
'bad' => 'It is really bad!',
'notime' => 'No time for it!',
'otheroption' => 'Other option:'
),
));
Now it works!
if ($this->getRequest()->isPost() && $form->isValid($_POST)) {
$data = $form->getValues();
var_dump($data);
} else {
var_dump("it didn't work!");
}
to
if ($this->getRequest()->isPost()) {
if($form->isValid($this->getRequest()->getPost()){
$data = $form->getValues();
var_dump($data);
} else {
var_dump("it didn't work!");
}
}
and remember put this to last line of action:
$this->view->form = $form;
i'm sorry, i speak English not well.
Related
I have 2 modal that each have a grecaptcha. I load the script once the first modal is opened and render the captcha for that specific modal afterwards. This is working as expected. But once i submit the form with the captcha, i get the following error:
Uncaught Error: Invalid reCAPTCHA client id: 1
This is the JS code of the captcha render
var grecaptcha_contact = 0;
var grecaptcha_newsletter = 0;
function renderCaptcha(grecaptchatype) {
// Render Google Captcha
function renderCall(grecaptchatype) {
var captcha = grecaptcha.render(grecaptchatype, {
'sitekey': 'SITEKEY_censored',
'theme': 'light'
});
}
// Check if Google Captcha already rendered
if(grecaptchatype === 'g-recaptcha-newsletter'){
if(grecaptcha_newsletter !== 0){
return false;
}
else{
// Render Google Captcha
renderCall(grecaptchatype);
grecaptcha_newsletter++;
}
}
else if(grecaptchatype === 'g-recaptcha-contact'){
if(grecaptcha_contact !== 0){
return false;
}
else{
// Render Google Captcha
renderCall(grecaptchatype);
grecaptcha_contact++;
}
}
}
// load google captcha script on show modal newsletter & contact us
$('#newsletterModal').on('shown.bs.modal', function () {
if(window.grecaptcha) {
renderCaptcha('g-recaptcha-newsletter');
}
else{
var attempts = 0;
$.getScript('https://www.google.com/recaptcha/api.js')
.done(function() {
var setIntervalID = setInterval(function() {
if (window.grecaptcha) {
clearInterval(setIntervalID);
renderCaptcha('g-recaptcha-newsletter');
return false;
}
else if (attempts >= 100) {
clearInterval(setIntervalID);
return false;
}
attempts++;
}, 100);
});
}
});
$('#contactModal').on('shown.bs.modal', function () {
if(window.grecaptcha) {
renderCaptcha('g-recaptcha-contact');
}
else{
var attempts = 0;
$.getScript('https://www.google.com/recaptcha/api.js')
.done(function() {
var setIntervalID = setInterval(function() {
if (window.grecaptcha) {
clearInterval(setIntervalID);
renderCaptcha('g-recaptcha-contact');
return false;
}
else if (attempts >= 100) {
clearInterval(setIntervalID);
return false;
}
attempts++;
}, 100);
});
}
});
This is the Newsletter Form:
<button aria-label="Newsletter" type="button" class="newsletterbutton" data-toggle="modal"
data-target="#newsletterModal">#lang('footer.blade.newsletter')</button>
<div class="modal fade" id="newsletterModal" tabindex="-1" role="dialog" aria-labelledby="newsletterModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title" id="newsletterModalLabel">#lang('footer.blade.receive_newsletter')</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{{ Form::open(['id' => 'newsletterform']) }}
{{ csrf_field() }}
<div class="modal-body">
<div class="alert"></div>
<div class="form-group">
{{ Form::label('newsletter_email', __('footer.blade.contact.email'), ['class' => 'col-form-label']) }}
{{ Form::email('newsletter_email', '', ['required', 'class' => 'form-control']) }}
</div>
<div class="row form-group">
<div class="col-sm-12 acceptrules">
{{ Form::checkbox('acceptrules', 'value', null, ['id' => 'acceptrules', 'required']) }}
<label for="acceptrules" class="control-label">
#lang('add_app.blade.acceptrules')<a class="privacypolicy_link" target="_blank" href="{{ route('privacy-policy') }}">#lang('add_app.blade.acceptrules_link')</a>#lang('add_app.blade.acceptrules_link2')
</label>
</div>
</div>
<div class="form-group g-recaptcha-div">
<div class="g-recaptcha-newsletter g-recaptcha-count" id="g-recaptcha-newsletter"></div>
#if($errors->has('g-recaptcha-response'))
<span>{{$errors->first('g-recaptcha-response')}}</span>
#endif
</div>
</div>
<div class="modal-footer modal-footer-recaptcha">
{{ Form::submit(__('footer.blade.apply_newsletter'), ['class' => 'btn btn-primary']) }}
{{ Form::button(__('footer.blade.close_newsletter'), ['class' => 'btn btn-secondary', 'data-dismiss' => 'modal']) }}
</div>
{{ Form::close() }}
</div>
</div>
</div>
I'm not sure but i think the captcha was working before. I'm not sure if i changed something in the code which broke it or something else that broke it (server/laravel configs). Someone has an idea where to go from here?
I checked on my php code and the error appears here in the captcha.php:
public function passes($attribute, $value)
{
$client = new Client();
$response = $client->post('https://www.google.com/recaptcha/api/siteverify',
[
'form_params' => [
'secret' => env('CAPTCHA_SECRET', false),
'remoteip' => request()->getClientIp(),
'response' => $value
]
]
);
$body = json_decode((string)$response->getBody());
return $body->success;
}
The getbody() response if success=false
The $attribute is g-recaptcha-response and the $value is a long key probably the public key encrypted.
The secret form_params seems false all the time. I'm not sure why is that, my env file has the captcha_secret set. I tried it with my secret key inside this function instead which did it. So there seems to be something wrong with my env secret key call. Maybe a caching problem or so, will try to figure it out myself from here.
AT my website you can create collaborators. I have a blade view with a table where you can see all of them. I want after creating new collaborator to return the main view of newly created collaborator.
I was thinking that I can either add it in my javascript function or maybe in route function instead of return back use like return view('person.profile.profile-view'); but I don't know how to pass all the data I need from a newly created field.
Also, my collaborator view needs a lot of data, here is the controller for it:
public function profileView($id)
{
$person = $this->personRepository->getByIdWith($id, ['person_title', 'country', 'salutation']);
$practitioner_id = $this->practitionerRepository->getIdByPersonId($id);
$practitioner = $this->practitionerRepository->getById($practitioner_id);
$specialty_id = PractitionerSpecialty::where('practitioner_id', $practitioner_id)->value('specialty_id');
return view('person.profile.profile-view')
->with('person', $person)
->with('id', $id)
->with('person_titles', $this->personTitleRepository->getAll())
->with('countries', Country::all())
->with('specialties', Specialty::all())
->with('specialty', Specialty::where('specialty_id', $specialty_id)->value('name'))
->with('competence_levels', CompetenceLevel::all())
->with('salutations', PersonSalutation::all())
->with('practitioner', $practitioner)
->with('practitioner_specialty', PractitionerSpecialty::where('practitioner_id', $practitioner_id)->first())
->with('practitioner_competence_level', PractitionerCompetenceLevel::where('practitioner_id', $practitioner_id)->first());
}
My php create form
<div class="modal fade crud-modal" id="create-Modal" tabindex="-1" role="dialog" style="z-index: 1050; display: none;"
aria-hidden="true">
[...]
<div class="modal-footer">
<button type="button" class="btn btn-default btn-round waves-effect "
data-dismiss="modal">{{trans('buttons.close')}}</button>
<button type="button" id="create_final_btn" class="btn btn-success btn-round"
>{{trans('buttons.add')}}</button>
</div>
</div>
</div>
</div>
var create = (function(){
var onSuccess;
var onHashSuccess;
var createButton = function(fieldValues, createUrl, required) {
$("#create_final_btn").click(function () {
forms.postObject(forms.readForm(fieldValues, '_create', undefined, required), createUrl, onSuccess);
});
};
[...]
var setOnSuccess = function(fun) {
onSuccess = fun;
};
var setOnHashSuccess = function(fun) {
onHashSuccess = fun;
};
return {
createButton: createButton,
createHashItemButton: createHashItemButton,
openCreateDialogButton: openCreateDialogButton,
setOnSuccess: setOnSuccess,
setOnHashSuccess: setOnHashSuccess,
openCreateTrainingPlanButton: openCreateTrainingPlanButton
};
}());
My function in routes:
public function addPerson(Request $request) {
$this->validate($request, [
'data' => 'required',
'data.first_name' => 'required',
'data.last_name' => 'required',
'data.active' => 'required',
'data.person_salutation_id' => 'required',
]
);
$this->repository->create($request->all()['data']);
return back();
}
I think the best way would be to do that in javascript function. If someone can lead me to the best solution that would be great.
Instead:
return back();
use
$object = $this->repository->create($request->all()['data']);
return redirect()->route('routename', ['id' => $object->id]);
I can save records in my custom table using $wpdb. One input of type submit is handled in javascript witch then uses fetch to send the data action and nonce to admin-ajax. My plugin has the add action function to sanitize and save the record in the database table.
I need to add a button that can delete that record which is where I am having problems. I have tried a separate php file but that cant find wpdb. So I am trying two buttons calling different actions but am unable to find suitable examples for wordpress ajax. My code is as follows
Form
<form id="changeCustAddr" action="#" method="post" data-url="<?php echo admin_url('/admin-ajax.php'); ?>">
<input type="hidden" name="action" value="cust_address">
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'cust_address_nonce' )?>">
<input type="hidden" id="record" name="record" value="<?php echo (!$newone) ? $rec : $max+1 ?>">
<input type="hidden" id="custno" name="custno" value="<?php echo $custno ?>">
input fields for addresses
Prev, Next and New buttons etc have been removed for clarity
<input type="submit" id="CustAddrDelete" name="delete" class="btn" value="Delete" data-url="<?php echo bloginfo('template_directory') ?>/scripts/deleteCustAddrform.php?cust=<?php echo $custno ?>&record=<?php echo $rec ?>" >
<input type="button" id="CustAddrNew" name="new" class="btn" value="New" data-url="<?php echo get_page_link( $post->ID ),'?cust=', $custno, '&record=new' ?>" >
<small class="field-msg js-form-submission">Submission in progress, Please wait …</small>
<small class="field-msg success js-form-success">Details Successfully submitted, thank you!</small>
<small class="field-msg error js-form-error">Could not update database. Please try again.</small>
<input type="submit" id="CustAddrSave" name="save" class="btn btn-blue" value="<?php echo (!$newone) ? 'Save' : 'Add New' ?>" data-action="cust_address">
<input type="button" id="CustAddrClose" name="close" class="btn btn-blue" value="<?php echo (!$newone) ? 'Close' : 'Discard Changes' ?>" data-url="<?php echo get_page_link( get_page_by_title( 'dojo details' )->ID ),'?cust=', $custno, '&record=1' ?>">
the javascript
document.addEventListener('DOMContentLoaded', function (e) {
const changeCustAddrFrm = document.getElementById('changeCustAddr');
if (changeCustAddrFrm) {
changeCustAddrFrm.addEventListener('submit', (e) => {
e.preventDefault();
let data = {
custno: changeCustAddrFrm.querySelector('[name="custno"]').value,
priority: changeCustAddrFrm.querySelector('[name="record"]').value,
address1: changeCustAddrFrm.querySelector('[name="address1"]').value,
... more address lines ...
postcode: changeCustAddrFrm.querySelector('[name="postcode"]').value,
}
// ajax http post request
let url = changeCustAddrFrm.dataset.url;
console.log(url);
let params = new URLSearchParams(new FormData(changeCustAddrFrm));
console.log(params);
changeCustAddrFrm.querySelector('.js-form-submission').classList.add('show');
fetch(url, {
method: "POST",
body: params
}).then(res => res.json())
.catch(error => {
resetMessages();
changeCustAddrFrm.querySelector('.js-form-error').classList.add('show');
})
.then(response => {
resetMessages();
if (response === 0 || response.status === 'error') {
changeCustAddrFrm.querySelector('.js-form-error').classList.add('show');
return;
}
changeCustAddrFrm.querySelector('.js-form-success').classList.add('show');
})
});
and the ajax called function
public function cust_address() {
if (!DOING_AJAX || !check_ajax_referer('cust_address_nonce', 'nonce')) {
return $this->return_json('error');
}
$custno = $_POST['custno'];
$addressno = $_POST['record'];
$max = $_POST['max'];
$servername = "localhost";
$username = "uuuu";
$password = "pppp";
$dbname = "db";
$mydb = new wpdb($username, $password, $dbname, $servername);
$table = 'mem_custaddress';
$data = [
'Address1' => sanitize_text_field($_POST['address1']),
// ... other address lines ...
'Postcode' => sanitize_text_field($_POST['postcode']),
];
$format = [ '%s', ... , '%s' ];
$where = [
'Custno' => $_POST['custno'],
'Priority' => $_POST['record']
];
$where_format = ['%d', '%d'];
if ($addressno <= $max) {
$result = $mydb->update($table, $data, $where, $format, $where_format);
} else {
$dataInsert = [
'Custno' => $_POST['custno'],
'Priority' => $_POST['record'],
'Address1' => $_POST['Address1'],
// ...
'Postcode' => $_POST['Postcode'],
];
$formatInsert = ['%d', '%d', '%s', ... , '%s'];
$result = $mydb->insert($table, $dataInsert, $formatInsert);
}
if ($result) {
return $this->return_json('success');
wp_die();
}
return $this->return_json('error');
wp_die();
}
public function return_json($status) {
$return = [
'status' => $status
];
wp_send_json($return);
wp_die();
}
How can I get the delete record to work?
after much searching I have come up with a solution. I hope someone can help tidy up the javascript. but the form data is now going to separate functions depending on the button pressed.
The form:
<form id="form1" data-url="<?php echo admin_url('/admin-ajax.php'); ?>">
<input type="text" name="field1" class="m-2 border-2">
<input type="text" name="field2" class="m-2 border-2">
<input id="s1" type="submit" name="press" value="Press" class="btn">
<input id="s2" type="submit" name="other" value="otherPress" class="btn">
</form>
The javascript:
const form1 = document.getElementById('form1'),
s1 = document.getElementById('s1'),
s2 = document.getElementById('s2');
s1.addEventListener('click', (e) =>{
e.preventDefault();
let f1data = new FormData(form1);
f1data.append('action', 'test');
let params = new URLSearchParams(f1data);
let url = form1.dataset.url;
fetch(url, {
method: 'post',
body: params
}).then(function (response){
return response.text();
}).then(function (text){
console.log('me', text);
}).catch(function (error){
console.error(error);
})
})
s2.addEventListener('click', (e) =>{
e.preventDefault();
let f1data = new FormData(form1);
f1data.append('action', 'other');
let params = new URLSearchParams(f1data);
let url = form1.dataset.url;
fetch(url, {
method: 'post',
body: params
}).then(function (response){
return response.text();
}).then(function (text){
console.log('me', text);
}).catch(function (error){
console.error(error);
})
})
and the ajax called functions:
add_action( 'wp_ajax_test', array($this, 'test') );
add_action( 'wp_ajax_other', array($this, 'other') );
public function test() {
var_dump($_POST);
}
public function other() {
var_dump($_POST);
}
I'm currently working on a AJAX login system, but it doesn't send any response back. It only sends a response back when I exit("error here") the script, but I want to return a JSON response.
My form:
<div id="account" class="modal" role="dialog">
<div class="modal-dialog">
<form method="post" id="login-form">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Sign in</h4>
</div>
<div class="modal-body">
<p>
Email address:<br />
<input type="email" class="form-control" placeholder="Email address" name="user_email" id="user_email" />
</p>
<p>
Password:<br />
<input type="password" class="form-control" placeholder="Password" name="password" id="password" />
</p>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-default" name="btn-login" id="btn-login">LOGIN</button>
</div>
</div>
</form>
</div>
</div>
My JavaScript:
$("#btn-login").click(function(e) {
alert('submit');
var data = $("#login-form").serialize();
alert(data);
$.ajax({
url: 'ajax.php',
type: 'POST',
data: data,
success: function(response) {
var data = response.responseText;
var resp = $.parseJSON(data);
if (resp.error) {
alert('error: ' + response);
} else {
alert('success: ' + response);
}
}
});
event.preventDefault();
});
My PHP:
if(isset($_POST['user_email']) && is_ajax()) {
$engine->expireLoginAttempts();
$engine->expireLoginBan();
if(!$engine->isLoginBanned()) {
$email = strip_tags($_POST['user_email']);
$password = strip_tags($_POST['password']);
if($engine->doLogin($email,$password)) {
$engine->expireBan();
if($maintenanc['value'] == '1' && !$engine->isStaff()) {
echo json_encode(array(
'success' => '0',
'message' => 'You can\'t login using a regular account because the site is currently under maintenance.'
));
} elseif($engine->isBanned() && !$engine->isOwner()) {
// Account banned; notify and give a timestamp + reason
$stmt = $engine->runQuery("SELECT timestamp, expiration, reason FROM banned WHERE user_id=:user_id");
$stmt->execute(array(':user_id'=>$_SESSION['user_id']));
$userRow = $stmt->fetch(PDO::FETCH_ASSOC);
$blockdate1 = strtotime('+' . $userRow['expiration'], strtotime($userRow['timestamp']));
$blockdate2 = date('d-m-Y H:i:s', $blockdate1);
echo json_encode(array(
'success' => '0',
'message' => 'This account is suspended until ' . $blockdate2 . ' because of the following reason: ' . $userRow['reason'] . '.'
));
} else {
echo json_encode(array(
'success' => '1',
'message' => $_SESSION['user_name'];
));
}
} else {
// Create login attempt if the account exists and the ip is different from the register ip
$stmt = $engine->runQuery("SELECT user_email, user_id, user_ip FROM users WHERE user_email=:email");
$stmt->execute(array(':email'=>$email));
$userRow = $stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1 && $userRow['user_ip'] !== $_SERVER["REMOTE_ADDR"]) {
$engine->createLoginAttempt($userRow['user_id'], $_SERVER["REMOTE_ADDR"]);
}
// Bruteforce attack suspected, bans the ip after 10 attempts from an unknown ip
$attemptban = $engine->runQuery("SELECT * FROM loginattempt WHERE ip=:ip");
$attemptban->execute(array(':ip'=>$_SERVER["REMOTE_ADDR"]));
if($attemptban->rowCount() > 4) {
if($engine->loginban()) {
$engine->deleteLoginAttempts($_SERVER["REMOTE_ADDR"]);
}
}
echo json_encode(array(
'success' => '0',
'message' => 'Emailaddress and/or password invalid.'
));
}
}
}
Does anybody know what I'm doing wrong? I've tried exiting the json_encode, putting exit() after each json_encode but none seem to work.. Any help is greatly appreciated!
Try add something to the else and see what's happened.
if(!$engine->isLoginBanned()){
...
} else {
// Try add something here and see what's happen, eg.
echo json_encode(array(
'success' => '0',
'message' => 'Sorry, isLoginBanned';
));
}
I am using dropzone file upload, when I return success / error from controller, how do I show it on my view file..
View file ,
<div class="box-body">
#if ( $errors->count() > 0 )
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ $message = 'Please select csv file only.' }}
</div>
#endif
{!! Form::open([ 'url' => 'admin/reports','class' => 'dropzone', 'id' => 'reportfile' ]) !!}
{!! csrf_field() !!}
<div class="col-md-12">
<h3 style="text-align : center">Select File</h3>
</div>
<button type="submit" class="btn btn-primary">Upload Report</button>
{!! Form::close() !!}
</div>
Controller Code
if ($request->hasFile('file')) {
$file = Input::file('file');
$validator = Validator::make(
[
'file' => $file,
'extension' => strtolower($file->getClientOriginalExtension()),
], [
'file' => 'required',
'extension' => 'required|in:csv',
]
);
if ($validator->fails()) {
return Response::json('error', 400);
}
JS Code
<script>
window.onload = function () {
Dropzone.options.reportfile = {
paramName: "file",
maxFilesize: 2,
error: function (file, response) {
alert('hiii')
},
init: function () {
this.on("addedfile", function (file) {
alert("Added file.");
});
},
accept: function (file, done) {
alert('hi')
if (file.name == "justinbieber.jpg") {
done("Naha, you don't.");
}
}
};
};
</script>
Not even alert is working...any help is much appreciated..Thanks
You should listen the events, and trigger whether it is success or not
Dropzone.options.uploadWidget = {
init: function() {
this.on('success', function( file, resp ){
alert("Success");
});
},
...
};
Note : You can have the other breakpoints as suggested here