I am using the validation.js from http://tetlaw.id.au/view/javascript/really-easy-field-validation to validate user input. This is what I am doing:
Validation.add('someClass', '', function(v, elm){
return myValidateFunction(this, checked.value, $(hID).value, $(wID).value);
});
In myValidateFunction I set the validation message for differnet situations like this:
if(something) {
validator.error = 'my message 1';
return false;
}
if(something else) {
validator.error = 'my message 2';
return false;
}
return true;
Problem is: If the first if was true on the first request the first time, I always get the first validation message (my message 1) on all coming requests, even though the second if was true. I also debugged the JS code and when myValidateFunction returns and I check this in the function call, it has the message I want, its just not displaying it correctly. What am I doing wrong?
Thanks!
I'd double check that 'something' is false on the subsequent calls. If 'something' remains true, then the second if statement will never be reached because you return false from the first if statement and the function exits.
Other than that it's a little hard to debug without some more code to see.
Related
I need to check if the pop up exists, if it does then I need to check if its displayed then perform certain action on it.
I have implemented the below. I was wanting to know if there is any better way of achieving this.
licenseUpdate.isPresent().then(function (item) {
if (item == true) {
licenseUpdate.isDisplayed().then(function (res) {
if (res == true){
licenseUpdate.click();
};
});
}
});
If you are using page object (you should) you can write something like this:
clickLicenseUpdate() {
const licenseUpdate = $(licenseUpdateCssSelector);
return licenseUpdate.isPresent()
.then((isPresent) => {
if (!isPresent) { return false; }
return licenseUpdate.isDisplayed();
})
.then((isDisplayed) => {
if (!isDisplayed) { return false; }
return licenseUpdate.click().then(() => true);
})
}
Note that if you are using and old JS version (you shouldn't) you need to replace arrow functions with traditional anonymous functions.
Some helpful links about Page Object Design Pattern:
PageObjects
Martin Fowler PageObject
Code explained (or at least, that is the plan):
Using $ to locate an element but you can use any strategy
supported by Protractor.
browser.findElement(by.className('license')) equivalent to
$('license'), browser.findElement(by.id('license')) equivalent to
$('#license'). Check Protractor documentation for more examples.
Once you a have found a web element that match your locator, you can
use isPresent method to determine whether the element is present on
the page. isPresent returns a promise that resolve to a boolean
value.
then always return a promise. You can return a primitive value from
onFulfilled callback and that value would be cast to a promise with
resolve with same value. That is what is done here: if (!isPresent) { return false; }; or you can return another promise
from onFulfilled callback and the promise returned by then will be resolved or rejected with same value of returned promise.
That is what is done here: return licenseUpdate.isDisplayed();. isDisplayed() also return a
promise that will resolve with whether this element is currently
visible on the page.
This can be a bit overwhelming if you are not
used to deal with promises. Check this out Promises/A+
Finally, if the element is present and is displayed, click the element with theclick method that, surprise, also return a
promise (WebDriverJS API is based on promises).
Note that if element is not present, isPresent is false in this
line if (!isPresent), returning false immediately bypass
licenseUpdate.isDisplayed() execution and resolve with a false value. In that
case isDisplayed value is false and again false is returned
immediately bypassing the licenseUpdate.click() execution.
Also note that clickLicenseUpdate return a promise that will
resolve to false if the element is not present or if is present but not
displayed. To keep clickLicenseUpdate returned value consistent, I recommend you to wait for licenseUpdate.click() and then return a boolean value as it is done here: return licenseUpdate.click().then(() => true); (using implicit return from arrow functions) because promise returned by click() resolve with a void value.
That is harmless but is considered a good practice maintain a consistent return value, always a boolean value, not sometime a boolean and others a void value.
I am using ember-cli:2.5.0 and ember-validations:v2.0.0-alpha.5
In my ember-component i have a validation which is running automatically for each change in a attribute but i want to run this validation only if i call "validate()" method in technical term call validation lazily.
Please find the below code samples,
import Ember from 'ember';
import EmberValidations, { validator } from 'ember-validations';
export default Ember.Component.extend(EmberValidations, {
didReceiveAttrs() {
this.set('newBook', this._bookModel().create());
},
_bookModel(data = {}) {
return Ember.Object.extend(EmberValidations, {
bookVersion: null,
isEditable: false,
validationActive: false,
validations: {
bookVersion: {
inline: validator(function() {
if(this.validationActive){ //Here this.validationActive always return undefined
var version = this.model.get('bookVersion') || "",
message = [];
if (Ember.isEmpty(bookVersion)) {
message.push("Book Version is mandatory!!!");
}
if (message.length > 0) {
return message.join(',');
}
}
})
}
}
}, data);
}
});
actions: {
this.get('newBook').set("validationActive",true);
this.get('newBook').validate().then(() => {
//Do the action
}
}
I want the above validation to run only calling "this.get('newBook').validate()". I am entirely new to ember so down-voter please put your comments before down-voting for others kindly let me know for any more code samples.
Your help should be appreciable.
The addon you are using for validations ("ember-validations") is a very popular one and its documentation is pretty well when compared to others. If you look at the documentation there is a part named "Conditional Validators" in documentation. You can use a boolean property to control when the validation is to be performed.
You can see an illustration of what I mean in the following twiddle. I have created a simple validation within the application controller for user's name. The name field must have a length of at least 5 and the validation is to be performed only if the condition validationActive is true. Initially; the condition is false; which means validator did not work and isValid property of Controller (which is inherited from EmberValidations Mixin) is true. If you toggle the property with the button provided; the validation will run (since the condition is now set to true; hence validation is triggered) and isValid will return to false. If you change the value; the validation result will change appropriately with respect to the value of user's name. If you toggle the condition once again to set it to false; then isValid will become true no matter what the valie of user's name is.
I hope this gives you an insight about how to control when your validations should work.
Here is what you should do after your edit: The field is undefined because you are trying to reach component's own validationActive field within inline validator. Please get validationActive as follows this.model.get('validationActive') and give a try. It should work.
This questions was about Backbone 0.9.2
Since upgrading to Backbone 0.9.10 we've chosen to override Backbone.sync instead and it works like a charm.
December 2012 - (v0.9.9) Backbone.wrapError has been removed.
February 2013 - It looks like WrapError will be brought back in the next version of Backbone, but overriding backbone.sync is the way to go.
(sorry for the long read)
I'm modifying the Backbone.wrapError function and I'm baffling by a line. I know what the line does, but not WHY it is necessary.
resp = model === originalModel ? resp : model;
resp ends up being the textStatus/errorType ie: "error" "timeout"
"parse error"
model is the XHR request object
originalModel is a reference to the Backbone.Model instance which ultimately called this function
I have a good grasp on what Backbone.wrapError does, what it returns and how it is used but I can't seem to understand the purpose of the above line.
Backbone's documentation states that wrapError will 'Wrap an optional error callback with a fallback error event,' which is true. Additionally, I've learned is that Backbone.wrapError is called 4 times in the library from within the fetch, save, destroy and reset functions in order to ensure that AJAX errors do not go unnoticed by the library. For example, if an AJAX error callback is passed into the fetch method it will be executed with a few parameters passed along, if not, the model will trigger an error event with the same few parameters passed along.
Sample call:
options.error = Backbone.wrapError(options.error, model, options);
Backbone.wrapError:
Backbone.wrapError = function(onError, originalModel, options) {
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
onError(originalModel, resp, options);
} else {
originalModel.trigger('error', originalModel, resp, options);
}
};
};
The problem that arises with this line (resp = model === originalModel ? resp : model;) is that model and resp correspond to the first 2 parameters within the jQuery/Zepto error callback parameter list. The first problem I have is with the naming of these parameters (model, response), because while debugging I've seen that those 2 parameters are jqXHR/xhr and textStatus/errorType. The textStatus/errorType parameters usually end up being "error" but (according to the docs) can also be "timeout" "parse error" etc. The comparison of model === originalModel makes no sense to me. A hard comparison on an XHR object and a Backbone.Model instance will always fail, and model will be stored into response (resp), which is fine because the model is actually the XHR response object... this line just seems pointless to me, but I went ahead and included it in my modified wrapError method.
Because model === originalModel always evaluates to false, the line seems to be an elaborate version of resp = model; which is useless, because you could just remove the line entirely and the model parameter could be passed into originalModel.trigger('error', originalModel, resp, options); instead of resp.
Is there any instance where model === originalModel could possibly evaluate to true?
Anybody with more experience in Backbone.js, AJAX have an answer/explanation of why this line is necessary?
TLDR/CLIFFS:
The weird little line below is used to determine weather the error callback was triggered from a failed validation at the model level, or from a failed AJAX call from the fetch, save, or destroy methods (which all call Backbone.sync). If the failure is from validation, it does not change the resp variable because resp should already hold useful information returned by validate (such as an errors array or a string about the error). If the failure is from a bad AJAX request, the XHR object is stored into resp because the XHR is the most informative item available. Unfortunately, the XHR is passed into this function as model and Backbone documentation fails to point out that this parameter does not always represent a model. Resp is meant to hold useful response information about the error(s), and is sent to the error callback or a thrown error event.
Okay. I learned some things about this weird line.
resp = model === originalModel ? resp : model;
In Backbone there are AJAX errors and Validation errors. Conveniently, Backbone funnels both errors into the same function -- the AJAX error callback. The problem is that the arguments passed into these functions are inconsistent. When there is an AJAX error an XHR object is available, but not during a validation error.
If there is no callback present, Backbone will throw and 'error' event with the same parameters that would have been passed into the error callback. (line 7 and 9 below).
After a successful AJAX request, your JSON data can be optionally passed through the model's validate function. In Backbone, the validate function should return false or nothing at all when there are no errors. When there ARE errors, it is typical to return an array such as ['invalid username', 'password too long', 'etc...'] Anything returned from validate (usually an error messages array) is passed into the 'wrapped' error callback as the resp parameter and the model itself is passed as model!
The _validate function is a bit sloppy and has multiple return statements, but when validation fails, line 9 is hit. Line 9 of the _validate function passes this (the model), error (returned from the models validate method), options (ajax options, success, error, timeout etc). This differs from an AJAX error which will pass in xhr (xmlhttprequest object), errorType ('error' 'timeout' 'parse error' etc), options (ajax options).
validate error: error(model, validate_return_value, options)
ajax error: error(xhr, errorType, options)
1 _validate: function(attrs, options) {
2 if (options.silent || !this.validate) return true;
3 attrs = _.extend({}, this.attributes, attrs);
4 var error = this.validate(attrs, options);
5 if (!error) return true;
6 if (options && options.error) {
7* options.error(this, error, options);
8 } else {
9 this.trigger('error', this, error, options);
10 }
11 return false;
12 }
The strange line of code above is necessary because, this one function handles errors from 2 different methods. AJAX and Validation. Those 2 send it different parameters, so this is meant to normalize them and throw events with consistent parameter lists.
When a validation error occurs, the model does not change so the model that is passed into the error callback is exactly equal to the originalModel. The purpose of the resp parameter is to hold information about the error itself. When there's an AJAX error, 'timeout' 'parse error' or 'error' are simply not as informative as the XHR object.
That weird little line determines weather the error callback was accessed from _validate or through a normal AJAX error such as a 404. When it is accessed from validate, resp is the value returned from validate. It should be informative, and useful data for the front-end templates to display. When the resulting error is from a HTTP error, the most useful information about that error is the XHR object which is passed into this function as the MODEL parameter.
A hopefully simplified approach to the wrapError and validate functions
Backbone.wrapError = function(ajax_error_callback, model_or_xhr, ajax_options) {
return function(model_or_xhr, error_info) {
if there was an ajax error, error_info = the xhr object
if there was a validation error, error_info = whatever was returned from validate
if there's an error callback {
run the error callback with (the original model, error_info, ajax_options) as parameters
if there is not an error callback
throw an event called 'error' with (the original model, error_info, ajax_options) as parameters
}
};
};
original:
Backbone.wrapError = function(onError, originalModel, options) {
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
* onError(originalModel, resp, options);
} else {
originalModel.trigger('error', originalModel, resp, options);
}
};
};
The * shows that error callback called from here
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reference - What does this error mean in PHP?
I am having an issue with the following section of code:
I can get the error notices in the validation but the next step = valid code I just get a white page, Any Ideas?
I have checked the error settings and I have set it in the public_html php.ini file and I still don't get errors
function create_sale()
{
$this->template->append_metadata( js('debounce.js', 'sales') );
$this->template->append_metadata( js('new_sale.js', 'sales') );
// -------------------------------------
// Validation & Setup
// -------------------------------------
$this->load->library('form_validation');
$this->sale_rules[1]['rules'] .= '|callback__check_slug[insert]';
$this->form_validation->set_rules( $this->sale_rules );
foreach($this->sale_rules as $key => $rule)
{
$sale->{$rule['field']} = $this->input->post($rule['field'], TRUE);
}
// -------------------------------------
// Process Data
// -------------------------------------
if ($this->form_validation->run())
{
if( ! $this->sales_m->insert_new_sale( $sale, $this->user->id ) ):
{
$this->session->set_flashdata('notice', lang('sales.new_sale_error'));
}
else:
{
$this->session->set_flashdata('success', lang('sales.new_sale_success'));
}
endif;
redirect('admin/sales');
}
$this->template->set('sale', $sale)
->build('admin/new');
}
You said that your code is valid but you get a white page.
Most of the time when you get a white page you will simply have an error in your code.
As is the case here:
You suddenly have an endif; in your code which you don't want there.
Enable error reporting please:
Include this code in your bootstrap file:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Remember to disable this in production!
To remove the error change:
if ($this->form_validation->run())
{
if( ! $this->sales_m->insert_new_sale( $sale, $this->user->id ) ):
{
$this->session->set_flashdata('notice', lang('sales.new_sale_error'));
}
else:
{
$this->session->set_flashdata('success', lang('sales.new_sale_success'));
}
endif;
redirect('admin/sales');
}
to:
if ($this->form_validation->run())
{
if( ! $this->sales_m->insert_new_sale( $sale, $this->user->id ) )
{
$this->session->set_flashdata('notice', lang('sales.new_sale_error'));
} else {
$this->session->set_flashdata('success', lang('sales.new_sale_success'));
}
redirect('admin/sales');
}
You have too many closing curly braces, remove the 'endif' in your script and it should work.
CodeIgniter is notorious for the "white screen of death".
Generally when I've run into it, it's been because of the way they set up their database error handling (it's not good). Database errors aren't handled when $db['default']['db_debug'] is set to FALSE. Any query or connection attempt that fails just returns false. Execution continues after a bad query, which can result in a white screen of death. If you're lucky, you'll get an error message in the logs in some cases, but in most you won't, as the query() function just silently returns false without logging anything.
If you set it to TRUE, then you can be in an even worse position, because any database error will automatically result in CodeIgniter calling it's own show_error() function and generating a 500 HTTP response, and you have no chance of handling it on your own.
This is the most common way to get the WSOD that I'm aware of. I haven't used the 2.0 versions of CI, but it was the case in the 1.7 versions. You may want to try setting db_debug to true in your database.php config file until you find out what's going on.
I suspect that your redirect() is failing to redirect (instead just leaving a blank page sans redirect) for some reason or another. Toss a debug message before it to check.
Ajax and Reflection
I am developing an ajax-based application and wondering, what role reflection plays or might play here?
Probably most importantly I am asking myself, if it would be a good approach to
handle all ajax responses through a single handler,
reflect or interpret the data or error
delegate further processing (e.g. where to inject the html) based upon the analysis.
Is this a budding procedure? What pros and cons come to mind?
Additional clearification
My current implementation, which I am not happy with, looks like this.
Register eventhandlers for user action, which lead to ajax requests.
For each request:
Determine which container is the target for the new content
Validate the ajax response
Pass the result to the appropiate rendering function if everything is as expected
Here is an example
function setGamedayScoringChangeHandlers() {
$("#community").delegate("div.community div.nav", "click", function() {
var orderId = $(this).html();
var communityId = $(this).closest('.communityView ').dashId();
requestGamedayScoringByOrderId(communityId, orderId);
});
}
function requestGamedayScoringByOrderId(communityId, orderId) {
var $targetContainer = $('#community-' + communityId + '-gameday');
$.ajax({
url: '?api=league&func=getGamedayScoringByCommunityIdAndOrderId',
data: {
communityId : communityId,
orderId : orderId
},
success: function(result) {
// custom indicator, that sth. didn't work as supposed
if (result.success === false) {
// a php error couldn't be handled as expected
if (result.error === 'phpRuntimeError') {
// ..
}
// ..
}
else {
renderGamedayScoring(result, $targetContainer);
}
}
});
}
Question
How can this and especially the redundant error checking be simplified? Could Reflection, in a sense of: "Is the response valid? And what does the error message say or data look like?" be a reasonable structure do deal with this? Additionally: Is the "coupling" of the actual ajax request and determing the $targetContainer a "normal" procedure?
Many thanks,
Robson
Yes I think register ajax handler trought one pipe is a good way, because it is more easy to control, you will have less redundant code and less boarding effects. If I look at your code comments it seems the response is not as you expect. I use to do like this for controling a group of ajax request talking with server script. I build one request object like :
// myscript.js
var rqPHP = {
url:'php/dispatcher.php', type:'POST', dataType:'json',
success:function(json, status, jXHR){
//console.log('rqPHP.succes : ', json);
if(!json) return console.warn('[rqPHP.success] json is null');
if(!json.cmd) return console.warn('[rqPHP.success] json.cmd is null');
if(!json.res) return console.warn('[rqPHP.success] json.res is null');
if(json.err && json.err.length){ console.warn('[rqPHP.success errors cmd:'+json.cmd+'] '+json.err);}
// so if no errors, dispatch actions based on original command asked
switch(json.cmd){
case 'loadfile' :
// do whatever with response
break;
case 'savefile' :
// do whatever with response
break;
}
},
error:function(jXHR, status, err){
console.warn('[rqPHP.error] ', status,',',err,',',jXHR.responseText);
}
};
then when use this object trought all my group of different actions and I precise wich action and arguments I pass. I use to ask for a json data so I am able to receive an easy parsing response, so I am able to return the original command asked, and some details on errors that may occured for example, and when I need to fire the request :
// myscript.js
rqPHP.data = {'cmd':'loadfile', 'filename':'file.dat', 'arg2':'other argument'};
$.ajax(rqPHP);
Then an example of one server script that will respond :
// dispatcher.php
$pv = $_POST;
$res = '';
$err = array();
// you check the command asked for :
switch(strtolower($pv['cmd'])){
case 'savefile' :
// do whatever
break;
case 'loadfile' :
// do whatever
if(any error){
$err[] = $loadError;// push error with whatever details you'll retrieve in javascript
}else{
$res = ',"res":"'.$dataLoaded.'"';// format json response so you'll check the var exist
}
break;
}
$jsonRes = '{"cmd":"'.$pv['cmd'].'"'.$res.',"err":"'.implode('|', $err).'"}';// json result
print $jsonRes;
They may be some errors, it is just for the principe, I hope that will help, just some last advices :
you should better use the requestObject.data to pass any arguments instead of setting the url like you did, this is much more easy because jQuery does the properly encoding work
you may use POST so the url stay clean, post vars are 'hidden'
in your case, because you may want to centralize server actions with ONE server script, you should use 'json' as dataType because it is much easier to retrieve details from the response, such errors. You have to distinct the ajax error that is trigger when the url doesn't exist, or access denied, well when the server replies it just can't respond to this request, and distinct the properly response of your server script, I mean the script responds well but it may occur an command error, for example for a 'loadfile' command, the argument fileUrl may be wrong or unreadable, so the action is done but the response will be not valid for you...
If you plan to fire many loads for differents parts (I mean you may don't wait response for an ajax before loading a new one), it should be better to set main success and errors functions for keeping centralization and then build one new request object each time you make a load
function rqSuccess(json, status, jXHR){
// put same checking code as before, then you can also retrieve some particular variables
// here, 'this' should correspond to the request object used for the $.ajax so :
console.log('myTarget is : ', this.myTarget, ' , myVariable is : ', this.myVariable);
}
function rqError(jXHR, status, err){
// put same checking code
}
// then each time you want make one or many independant calls, build a new request object
var myRq = {url:'dispatcher.php',type:'POST',dataType:'json',
success:rqSuccess,
error:rqError,
myTarget:$('#myblock'),// any variable you want to retrieve in response functions
myVariable:'Hello !',// after all it is an object, you can store anything you may need, just be carefull of reserved variables of the ajax object (see jQuery $.ajax doc)
// the data object is sanitized and sended to your server script, so put only variables it will need
data : {'cmd':'loadfile',...}
}
$.ajax(myRq);
// you may load an other independant one without waiting for the response of the first
var myRq2 = {...myTarget:$('#anotherblock'), data:{'cmd':'anotheraction'}...}
$.ajax(myRq2);
As a first step, you should change the error handling on the serverside to produce a non-OK/200 response for error cases, e.g. throw a 500. Then have that handled as an actual error on the clientside, along with other errors, instead of putting it through the success-callback.
That way you can use jQuery's abstractions for global error handling: http://api.jquery.com/ajaxError