Juergen Posted May 12, 2016 Share Posted May 12, 2016 Hello @ all, I am using the following js-framework to validate my frontend forms: http://formvalidation.io/ My goal is to check if username and password match via Ajax, so the customer will see immediately if the entered values are correct or not. For this reason I have included the following js snippet inside the template with the login form. <?php $ajaxlogin = $pages->get("template=jsonlogin"); $ajaxloginurl = $ajaxlogin->httpUrl; ?> <script> $(document).ready(function() { $('#mainlogin-form').formValidation({ framework: 'bootstrap', icon: { valid: 'fa fa-check', invalid: 'fa fa-remove', validating: 'fa fa-refresh fa-spin' }, fields: { user: { verbose: false, validators: { notEmpty: { message: '<?php echo _t('Username missing! Please enter your username', 'Login');?>' }, different: { field: 'pass', message: 'The username and password cannot be the same as each other' }, } }, pass: { verbose: false, validators: { notEmpty: { message: '<?php echo _t('Password missing! Please enter your password', 'Login');?>' }, different: { field: 'user', message: 'The username and password cannot be the same as each other' }, remote: { url: '<?php echo $ajaxloginurl;?>', data: function(validator) { return { user: $('[name="user"]').val(), pass: $('[name="pass"]').val() }; }, message: 'Dont match' } } } } }); }); </script> This script should send the values of the fields user and pass to the backend (json file). Field username = user, field password = pass. The backend file looks like this: <?php //check if password and username match $match = true; $username = $input->get['user']; $pass = $input->get['pass']; $u = $users->get($username); //check if userid and password/temp password match if (($u->id && ($u->pass == $pass)) OR ($u->id && ($u->tmp_pass == $pass))){ $match = true; } else { $match = false; } // Finally, return a JSON echo json_encode(array( 'valid' => $match, )); ?> It should return true if both values match and false if not. In this case the username check works as standalone, but the combination of username and password match not. I can also not check if the password is in the db as standalone - this is probably a reason that it is not stored as a standard value. So I guess the problem could be in the jsonfile and not in the js file. It would be great if a user also uses this validation framework and can help me out. Here is another link that probably can help: http://stackoverflow.com/questions/27143058/bootstrap-validator-send-all-input-field-values-to-remote-php-file Thanks in advance 1 Link to comment Share on other sites More sharing options...
Juergen Posted May 12, 2016 Author Share Posted May 12, 2016 Ok I have figured it out. But one problem remains: User is logged in automatically without clicking the submit button. So if the username and password are entered correctly the user is logged in. Is there a way to prevent this. Here is the working code for others who are interested in: Js validation code: <script> $(document).ready(function() { $('#mainlogin-form').formValidation({ framework: 'bootstrap', icon: { valid: 'fa fa-check', invalid: 'fa fa-remove', validating: 'fa fa-refresh fa-spin' }, fields: { user: { verbose: false, validators: { notEmpty: { message: '<?php echo _t('Username missing! Please enter your username', 'Login');?>' }, different: { field: 'pass', message: 'The username and password cannot be the same as each other' }, } }, pass: { verbose: false, validators: { notEmpty: { message: '<?php echo _t('Password missing! Please enter your password', 'Login');?>' }, different: { field: 'user', message: 'The username and password cannot be the same as each other' }, remote: { url: '<?php echo $ajaxloginurl;?>', data: function(validator) { return { user: $('[name="user"]').val(), pass: $('[name="pass"]').val() }; }, message: 'Dont match' } } } } }); }); </script> Here is the changed code from the json file: <?php //check if password and username match $match = true; $username = $input->get['user']; $pass = $input->get['pass']; $u = $users->get($username); //check if log in with temp pass if ($u->id && $u->tmp_pass && $u->tmp_pass === $pass) { // user logging in with tmp_pass, so change it to be their real pass $u->of(false); $u->pass = $u->tmp_pass;//set temp pass value as pass value $u->tmp_pass = '';//delete temp pass value $u->save(); $u->of(true); } //try to login with password and username if ($session->login($username, $pass)) { // login successful $match = true; } else { //password and username dont match $match = false; } // Finally, return a JSON echo json_encode(array( 'valid' => $match, )); ?> This code line is responsible for the automatic login: if ($session->login($username, $pass)) {..... Is there a way to prevent this? I have asked a new question to this specific topic: https://processwire.com/talk/topic/13265-how-to-check-if-username-and-password-match-in-pw/?p=119972 Therefore this topic is solved. Link to comment Share on other sites More sharing options...
bernhard Posted May 13, 2016 Share Posted May 13, 2016 thank you jürgen, http://formvalidation.io/ looks awesome! would have needed this some weeks before for some quite complex forms... Link to comment Share on other sites More sharing options...
Juergen Posted May 13, 2016 Author Share Posted May 13, 2016 Hello bernhard, unfortunately the developer makes the latest versions commercial, but there is a version for free on jsdelivr.net Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 13, 2016 Share Posted May 13, 2016 It's probably not as feature rich, but I really like nette forms, where I can define validation rules for both client side and server side at once. The library is so nice to include a simple js file, to handle client side validation, which is additionally quite easy to enhance / change to ones specific needs. 3 Link to comment Share on other sites More sharing options...
tpr Posted May 13, 2016 Share Posted May 13, 2016 It's probably not as feature rich, but I really like nette forms, where I can define validation rules for both client side and server side at once. The library is so nice to include a simple js file, to handle client side validation, which is additionally quite easy to enhance / change to ones specific needs. So true! The default renderer is enough 99% of the time but there is the manual rendering where you can build the markup as you like it. I've done in a recent project and it's really awesome. Will post a screenshot later. Do you use the default validation Js or live-form-validation.js? I use the latter, the fork by Robyer, I found this to be the best maintained: https://github.com/Robyer/nette-live-form-validation Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 13, 2016 Share Posted May 13, 2016 I'm using a modified version of the default js file provided by nette. Didn't know about the other one by now. For rendering I'm using a custom Renderer class, which extends the framework's own one. This keeps it clean and is way easier than e.g. modifying ProcessWire's form markup output. Link to comment Share on other sites More sharing options...
tpr Posted May 13, 2016 Share Posted May 13, 2016 I do not use PW's form markup at all but Nette Form elements. Renderer is easy to customize, eg. $required_asterix = Html::el('sup')->setClass('asterix')->setText('*'); $colon = Html::el('span')->setClass('colon')->setText(':'); $renderer->wrappers['form']['container'] = 'div class="form-wrapper"'; $renderer->wrappers['controls']['container'] = 'div'; $renderer->wrappers['control']['container'] = 'div'; $renderer->wrappers['control']['description'] = 'p class="form-description"'; $renderer->wrappers['error']['container'] = 'ul class="help-block text-danger form-error"'; $renderer->wrappers['label']['suffix'] = $colon; $renderer->wrappers['label']['requiredsuffix'] = $required_asterix; As I wrote modifying the markup this way is well enough for simpler forms, and even for larger forms if there are no fancy things. Here is a quick screencap where I used manual rendering, which allows custom markup. Form fields are defined separately, and you can retrieve the full control, or only the label or control, error parts, etc. I like the freedom it gives. <div class="form-wrapper" n:if="$rsvpForm"> <fieldset> <legend><span><strong>Personal data</strong></span></legend> <p class="checkbox-wrap"> {$rsvpForm[participation_toggle]->getControlPart()} <label for="cf_participation_toggle">We attend the wedding</label> <span class="slideToggle">{$rsvpForm[participation_toggle]->getLabelPart()}<strong></strong></span> <label for="cf_participation_toggle">Unfotunately we cannot attend the wedding</label> </p> <div id="personal_data"> <div> <div class="input-wrap">{$rsvpForm['name']->control->cols(35)} {$rsvpForm['name']->error}</div> <div class="input-wrap">{$rsvpForm['email']->control->cols(35)} {$rsvpForm['email']->error}</div> <div class="input-wrap">{$rsvpForm['phone']->control->cols(35)} {$rsvpForm['phone']->error}</div> </div> </div> </fieldset> ... 5 Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 13, 2016 Share Posted May 13, 2016 Just changing the markup elements wasn't flexible enough for my usecase and manually putting all those form parts in their wrapper markup isn't a option as well, as the form is dynamically adjusted to which data the current user does need to supply (by role and such things). That's why I went with the custom renderer class. Just doing a 'echo $form' does render the complete form with markup just as I need it to be. 1 Link to comment Share on other sites More sharing options...
tpr Posted May 13, 2016 Share Posted May 13, 2016 Well you can dynamically build your form too, eg. if($user->hasRole('role_name')) { $form->addTextarea('result_to_see', _t('What is the result you would like to see?', 'Form'), 50, 3) ->setRequired(_t('Required field', 'Form')) ->setOption('character-counter', array('mode' => 'down', 'msg' => _t('%d characters left', 'Form'))) ->setAttribute('data-autosize') ->setAttribute('maxlength', 500); } $preferences = array( 'trial' => 'I would prefer to start with a small trial project to see how we can work together.', 'resolve' => 'I have a specific inquiry, and just want this issue to get resolved.', 'best-roi' => 'I want to go big. Let’s see how we can achieve the best return on investment overall.' ); if($something) { $preferences['anotherItem'] = 'Anther radio button'; } $form->addRadioList('preferences', _t('Please set the preference that best suits you', 'Form'), $preferences) ->setRequired(_t('Required field', 'Form')); echo $form; But you see what fits better for your project. 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 13, 2016 Share Posted May 13, 2016 And if you've more than a handful of fields you save yourself the hassle of writing all those if statements. <?php $needed = [ 'my-field', … ]; $addIfNeeded = function($fieldname, callable $callback) use ($form, $needed){ if(!in_array($fieldname, $needed)) return; $callback($form, $fieldname); }; $addIfNeeded('my-field', function($form, $fieldname){ $form->addText($fieldname, __('My Field')) ->setRequired(__('My field is required')); }); $addIfNeeded(…); $addIfNeeded(…); Link to comment Share on other sites More sharing options...
tpr Posted May 13, 2016 Share Posted May 13, 2016 I haven't gone that far and I really hope I never need to 2 Link to comment Share on other sites More sharing options...
szabesz Posted May 13, 2016 Share Posted May 13, 2016 Will post a screenshot later. That's cool, but please do not forget to publish your Nette Forms module either when the time comes (Just kidding, I'm sure you will not "forget" it.) Link to comment Share on other sites More sharing options...
bernhard Posted May 15, 2016 Share Posted May 15, 2016 thank you lostkobrakai and tpr for your insights to nette forms! i will try that Link to comment Share on other sites More sharing options...
tpr Posted May 15, 2016 Share Posted May 15, 2016 Maybe you should wait for my Nette forms module indeed. Seem like I don't manage to hide it forever It's functional and I use it on many production site but given the complexity of forms it's still only in alpha state. It's more about how I solved integrating Nette forms into PW, but still, there are areas I haven't explored. 4 Link to comment Share on other sites More sharing options...
bernhard Posted May 15, 2016 Share Posted May 15, 2016 sounds cool, but i don't have time to wait maybe i can try to work with it on my current project and help testing? Link to comment Share on other sites More sharing options...
tpr Posted May 15, 2016 Share Posted May 15, 2016 PM sent. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now