Introduction
This article explains how to easily turn standard text-line validation errors into beautifully and professionally looking Twitter Bootstrap's Popovers.
Solution is quite easy (very easy) and can be implemented in nearly every project, no matter which Bootstrap extension for Yii you're using (Yii-Bootstrap, Yii-Booster, YiiStrap). It can be also easily implemented, if you're not using it at all, i.e. if you're adding Twitter Bootstrap to your project manually, by referencing its CSS and JS files.
The code
Javascript code
We need a quite simple Javascript function. For example something like this:
/**
* Adds client-side forms validation as Bootstrap's Popovers.
*/
function afterValidateAttribute(form, attribute, data, hasError)
{
var field = (attribute.hasOwnProperty('id')) ? attribute['id'] : '';
if(field !== '')
{
var text = (data.hasOwnProperty(field)) ? data[field] : '';
field = '#' + field;
if(hasError && (text !== ''))
{
/**
* 'destroy' is neccessary here, if your field can have more than one
* validation error text, for example, if e-mail field can't be empty
* and entered value must be a valid e-mail; in such cases, not using
* .popover('destroy') here would result in incorrect validation errors
* being displayed for such field.
*/
$(field)
.popover('destroy')
.popover
({
trigger : 'manual',
content : text
})
.popover('show');
}
else $(field).popover('destroy');
}
}
You can register it using clientScript or simply put it to any of your *.js files and reference it in you layout.
PHP Code
In your form's widget definition (i.e. in line starting with $form = $this->beginWidget('CActiveForm', array()) and 'enableClientValidation'=>true to configuration array.
Then create another array like this:
$validationArray = array
(
'hideErrorMessage'=>TRUE,
'afterValidateAttribute'=>'js:afterValidateAttribute'
);
Finally, print out your validation-error area using standard way and above configuration array:
Note. I'm using afterValidateAttribute event here, instead of overwriting clientValidation, because second one seems to have some bugs in current implementation. More details here. If these bugs will be fixed, we will be able to change this solution and at least some of strange issues explained below will be gone.
Some strange issues
Presented solution works best, when you're using Twitter Bootstrap extension only for additional GUI elements like Popovers, but you're building your form using standard CActiveForm. If you decide to use TbActiveForm you may run into several strange issues, as in current implementation, it has some bugs. This is mainly because, when using CActiveForm you're using three different commands (functions) to render: label, field and error area separately. While in TbActiveForm all these three fields are rendered internally for you.
Custom validation classes
Using 'hideErrorMessage'=>TRUE, blocks Yii from displaying a standard text-like validation error, but does not blocks it from changing classes (look) of fields being validated. You can control styles of that fields during each step (validation, error or success), by attaching own classes or setting them to empty string to disable this feature.
To achieve this, you would normally use a bit enhanced configuration array. For adding own classes (changing style and look of fields being validated):
$validationArray = array
(
'hideErrorMessage'=>TRUE,
'errorCssClass'=>'myclasserror',
'successCssClass'=>'myclasssuccess',
'validatingCssClass'=>'myclassvalidating',
'afterValidateAttribute'=>'js:afterValidateAttribute'
);
or for disabling this feature (making fields not changing at all during client-side validation process):
$validationArray = array
(
'hideErrorMessage'=>TRUE,
'errorCssClass'=>'',
'successCssClass'=>'',
'validatingCssClass'=>'',
'afterValidateAttribute'=>'js:afterValidateAttribute'
);
This works just fine using CActiveForm. If you decide to use TbActiveForm, it will not work, as in current implementation errorCssClass, successCssClass and validatingCssClass attributes seems to be ignored and are always set to default values.
Post-submit validation
Since TbActiveForm is rendering error-fields for you internally, you don't have access to it and you can't disable it. This means, that using TbActiveForm you have to error-fields for each editing field -- one renderend internally by TbActiveForm and second, added manually by you. This means, that after submitting form your user will see two error message per each field, which did not passed validation.
To make things even worse, both of these errors will be again standard, line-text errors. I have no idea, how to use Bootstrap's Popovers to display validation errors after form submit.
Summary
Using Twitter Bootstrap's Popovers to display client-side validation errors instead of standard line errors does seems to be a good idea. But keep in mind that this solution works best when you're dealing with CActiveForm. Expect many strange issues when you use TbActiveForm.
Let's hope that next-generation Bootstrap for Yii (Yiistrap + YiiWheels) will have all such issues fixed.
This article shows one of possible ways to implement menu items (as well as links), which displays a progress / wait dialog and are redirecting browser to destination URL in the same time. This is especially useful, for links or routes that are know to be loaded for a prolonged period of time (i.e. getting a lot of data from database).
Note: This example comes from my very old project, so the code is not that perfect as I would wrote it now. Consider this as just a start point for you, for further reasarch. Feel free to introduce any corrections or enhancements, you would like to this article.
Introduction
The general idea is to display some dialog box, using JavaScript or jQuery and initiate browser redirection in the same time (in response to one click event). If you implement proposed solution, you don't have to take care about hiding already open wait-dialog, because when page is finally redirected to destination, wait-dialog is all gone (part of browser history! :]).
I'm showing an example based on menu. But since menus, CGridView's columns and buttons confguration are quite similar (based on associative arrays and well known attributes), this solution can be easily adapted for example to a link, button or grid view column.
The code
PHP code
Consider following array as one menu item:
array
(
'label'=>'Results',
'linkOptions'=>CFR::getLoaderArray
(
'Loading results module',
'Getting data from database!',
array('/results/index')
),
'active'=>(app()->controller->id == 'results')
)
For convinience (attaching to many menu items, links, buttons etc.) key configuration array is not expressed directly and is instead generated using following function:
/**
* Builds params list (htmlOptions) used to call wait-loader.
*
* @param string Window title.
* @param string Message, that appears in a window.
* @param string Destination URL, where page should be redirected after displaying wait-dialog.
* @param array Additional htmlOptions merged with function ones.
*
* @return array Associative array in htmlOptions format, ready to be binded to a menu, button etc.
*/
public static function getLoaderArray($title, $contents, $url = '', $htmlOptions = array())
{
$url = CHtml::normalizeUrl($url);
$onClick = 'showLoaderDialog(\''.$title.'\', \'Please wait...'.$contents.'\'';
$onClick = ($url != '') ? $onClick.', \''.$url.'\')' : $onClick.')';
$baseArray = array('onclick'=>$onClick, 'encode'=>false);
$baseArray = array_merge($htmlOptions, $baseArray);
return $baseArray;
}
Javascript code
Functions showLoaderDialog() and hideLoaderDialog() are Javascript functions defined this way:
As you may see, you may use this solution without passing URL, which will result in displaying wait dialog without actual browser redirection. But I can't think of many situations, where such feature would be usefull?
The view
Key part of entire solution is a partial view, which holds actual wait (progress) dialog (and above mentioned two Javascript functions). I used CJuiDialog for this purpose, but you can of course use anything you want or even design your wait dialog manually.
Here is wait dialog binded inside partial view:
Notice, that this part: 'htmlOptions'=>array('style'=>'display: none') is necessary for some old versions of Internet Explorer, in which dialogs were not correctly hidden using CJuiDialog (jQuery) internals.
Now, because entire engine of this solution (both view and responsible Javascript functions) are stored in one partial view (stored in /protected/views/layouts/_wait.php), all I had to do, was to add renderPartial call to my main layout file (/protected/views/layouts/main.php):
just below tag.
This ensured, that I'll have my wait-dialog always rendered, in any view, no matter, if I want it or not. This was also necessary, because my menu definition (where I mostly used my wait-dialogs) was also stored in main layout file. However, if you're planning to use this solution only in certain situations, it is better to use renderPartial directly in a view, where you want to use your wait-dialog. Do not add it to your layout file in this case.
Final words
As I mentioned in the beginning, this is quite old solution and it is not coded (or designed) with highest standards. But it can be a good start point for anyone wishing to develop something better or more professional.
I am trying to build an HTML 5, JS mobile app. I need to make use of service that has exposed its API in the following format
I am trying to understand how can I make use of this using Java script and HTML? A sample code of invoking this API and using the response would be much appreciated.. thanks
Request
To use the Article API, perform a HTTP GET request on the following endpoint:
http://www.diffbot.com/api/article?token=...&url=...
POSTing Content
Alternatively, you can POST content to analyze directly to the same endpoint:
http://www.diffbot.com/api/article?token=...&url=...
*Example Response
{
"url": "htt://xxxxxxxxxxxxxxxxl",
"title": "Little Bunny Foo Foo",
"author": "Mother Goose",
"date": "yesterday",
,
"text": "Little bunny foo foo, Hopping through the forest, Scoopin' up the field mice,
Bop'em on the head. Down came the Good Fairy and she said...",
"tags":["Nursery Rhymes", "Mother Goose"],
"xpath": "/HTML[1]/BODY[1]/CENTER[1]/DIV[1]/DIV[2]"
}
I have tried the following code: but it doesn't seem to finish the GET command and never goes into the process() method
var xmlDoc = null ;
function load() {
if (typeof window.ActiveXObject != 'undefined' ) {
xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
xmlDoc.onreadystatechange = process ;
}
else {
xmlDoc = new XMLHttpRequest();
xmlDoc.onload = process ;
}
xmlDoc.open( "GET", "http://www.diffbot.com/api/article?token=dummytoken&url=http://www.hidden.com", true );
xmlDoc.send( null );
}
function process() {
if ( xmlDoc.readyState != 4 ) return ;
document.getElementById("output").value = xmlDoc.responseText ;
}
function empty() {
document.getElementById("output").value = '' ;
}
Load
Clear
I have installed pycharm 125.92 openjdk 1.7.0_15 on ubuntu 12.10 x64
So, the problem is when i open document and try to scroll it, pycharm opens recent documents and scroll throughout them. Any suggestion why it happens?
Thanks
I am unable to post image in windows phone which is converted into array of byte,here is mycode-
var client = new WebClient();
client.DownloadStringCompleted += dataSubmitCompleted;
client.DownloadStringAsync(new Uri(
"here url/Service1.svc/saverecord3" + convertImageToArray(bitmapImage1),
UriKind.Absolute));
here convertImageToArray is method which convert photo to byte array
I have read dozens of solutions to similar transposition problems as the one I am about to propose but oddly none that exactly mirrors my issue. I am simply trying to flip my rows to columns in a simple dashboard type data set.
The data when pulled from various transaction tables looks like this:
DatePeriod PeriodNumberOverall Transactions Customers Visits
'Jan 2012' 1 100 50 150
'Feb 2012' 2 200 100 300
'Mar 2012' 3 300 200 600
and I want to be able to generate the following:
Jan 2012 Feb 2012 Mar 2012
Transactions 100 200 300
Customers 50 100 200
Visits 150 300 600
The metrics will be static (Transactions, Customers and Visits), but the date periods will be dynamic (IE - more added as months go by).
Again, I have ready many examples leveraging pivot, unpivot, store procedures, UNION ALLs, etc, but nothing where I am not doing any aggregating, just literally transposing the whole output. I have also found an easy way to do this in Visual Studio 2005 using a matrix with an embedded list, but I can't export the final output to excel which is a requirement. Any help would be greatly appreciated.