jQuery call function when language in selectbox is changed - javascript

I have the following problem.
To translate a website, I'm using the jQuery Localize plugin.
This works fine. However, I want a CSS styled selectbox with flags and languages, and when a different option is selected the call to $("[data-localize]").localize("example", { language: $(this).attr('value') should be made to translate the page.
This code I'm currenly using, and it works fine for a plain, not-styled selectbox.
<script type="text/javascript">
$(function() {
$('#polyglot-language-options').change(function() {
if ($(this).attr('value') == "en") {
$("[data-localize]").localize("example", {
language: $(this).attr('value')
});
}
else if ($(this).attr('value') == "nl") {
location.reload();
}
});
});
</script>
But I want to style it, so I tried to integrate the "polyglot" language switcher. However, the current code doesn't work.
How can I integrate the $("[data.localize]").localize(); function in this code:
$('#polyglotLanguageSwitcher').polyglotLanguageSwitcher({
effect: 'fade'
});

This plugin (source code) does not follow the guidelines for jQuery plugin design. The bugs I found quickly:
It does not allow chaining, because it does not return this
It works only on one element at a time (does not use each())
It has a queer element hierarchy. It seems to require an element with an id, containing a form containing a select (as in the demo). In my opinion, such a plugin should be called on the language select element only.
It seems to navigate automatically, wanting to be configured with the page structure. Each of the li items in that fancy box contains a link to the respective page.
Therefore, it does neither trigger the form it live in or fire the change event you want to listen to.
As it stands, you can't use this particular plugin as you want to. If you want to fix all the bugs, I wish you a happy time :-) Nonetheless it might be possible to manipulate the plugin code, to let you register callbacks on select events (where you can invoke the localisation plugin). Otherwise, you will need to choose an other select plugin (or build one yourself from scratch, adapting the existing code)

Related

Apply jquery mobile only a portion of page?

I have a sample page which we have design very well. Now, we need to use jquery mobile only a portion of our page. The problem is that, when I add jquery mobile it is messing all my UI stuff. Is there is a way to apply jquery mobile only a portion of page?
There are several ways of achieving this, and you can find them in my other ARTICLE, or find it HERE. Search for chapter called: Methods of markup enhancement prevention.
And here's a short description with examples. There are several solutions and you will need to pick right one:
Methods of markup enhancement prevention:
This can be done in few ways, sometimes you will need to combine them to achieve a desired result.
Method 1:
It can do it by adding this attribute:
data-enhance="false"
to the header, content, footer container.
This also needs to be turned in the app loading phase:
$(document).one("mobileinit", function () {
$.mobile.ignoreContentEnabled=true;
});
Initialize it before jquery-mobile.js is initialized (look at the example below).
More about this can be found here:
http://jquerymobile.com/test/docs/pages/page-scripting.html
Example: http://jsfiddle.net/Gajotres/UZwpj/
To recreate a page again use this:
$('#index').live('pagebeforeshow', function (event) {
$.mobile.ignoreContentEnabled = false;
$(this).attr('data-enhance','true');
$(this).trigger("pagecreate")
});
Method 2:
Second option is to do it manually with this line:
data-role="none"
Example: http://jsfiddle.net/Gajotres/LqDke/
Method 3:
Certain HTML elements can be prevented from markup enhancement:
$(document).bind('mobileinit',function(){
$.mobile.page.prototype.options.keepNative = "select, input";
});
Example: http://jsfiddle.net/Gajotres/jjETe/

Expanding an Accordion Pane on Invalid Validation

I have a collection of AccordionPanes containing various TextBox controls and DropDownLists, each with their own validators.
If a few server-side validations occur on form submit, is there something that can automatically expand a previously minimized pane that contains the invalid validator message? Otherwise, it will seem to the user that the form isn't submittable without reason.
Another scenario: Let's say I have multiple panes with client side validators tied to the inputs. If a pane is minimized (and therefore you can't see the validator's ErrorMessage), is there a way to expand the appropriate pane when the AJAX page validation occurs on submit?
I know there's a brute-force way to this approach, where I keep track of every validator and their associated AccordionPane, but I was hoping for a better solution that can handle my situation for a large number of inputs/validators and panes.
How about something like this (using JQuery but I'm sure it can be converted into plain javascript)...
$(document).ready(function(){
if (isPostback()){
$.each(Page_Validators, function(index, validator) {
if (!validator.isvalid) {
// do something here to locate the accordion based on the validator
// $(this) is the currently invalid validator element as a jquery object/wrapped set
// so for example...
$(this).parent().slideDown();
// This assumes that the immediate parent of of the validator is the accordion which is unlikely but if you post your emitted html I can write the appropriate selector for you.
}
});
}
});
Because you dont want it to fire on initial load you can use a technique like this How to detect/track postback in javascript? and check if you are in a postback after the document.ready - I have assumed you've used the advice in the link and your function for postback detection is called isPostback().
there is a project built for this issue try to take a look at it....you can also download the source to analysis more details or use the same code-base if you want....http://www.codeproject.com/Articles/43397/Validating-Accordion-and-RadPanelBar-using-Ajax-an
Rich beat me to it, but here's the vanilla js version (ie9+):
Page_Validators
.filter(function(v) { return !v.isvalid; })
.forEach(function (v) { console.log(v.parentNode); });
Remember to place the code beneath the </form>-tag. I've had issues with using jQuerys document.ready and window.onload, since it might execute the code before all the needed JavaScript from asp.net is loaded.
Update: A more browser compatible version
for(var i = 0; i < Page_Validators.length; i++) {
var validator = Page_Validators[i];
if (!validator.isvalid) {
console.log(validator.parentNode);
}
}

jQuery breaks if function does not exists

Tinymce stops working if on the same page I use the selectmenu from https://github.com/fnagel/jquery-ui
Tinymce with default configuration
and selectmenu:
$('select.flags').selectmenu();
EDIT:
The problem is that on the page with tinymce i dont load the script for the selectmenu function. Should I remove it from the js that runs all the functions or is there any way to modify it to run only if the function exists and will be able to be ran
Here is an easy way to make 'function does not exist' problems go away.
$.fn.selectmenu = $.fn.selectmenu || $.noop
$('select.jquery_smenu').selectmenu(); //do what you will
or you could do it like this:
if( $.fn.selectmenu ){
$('select.jquery_smenu').selectmenu(); //do what you will
}
for the record, function does not exist or var is not a function is a javascript problem more than a jQuery one. Hope this helps!
Is tiny working with this script added to the page, but not initialized for the selects?
You apply selectmenu to every single select on your page.
tinymce uses selects and your surely don't want to change these.
Give your selects a class like
<select class="jquery_smenu"> ....
and change your selector:
$('select.jquery_smenu').selectmenu();
I can not test if thats the reason why tiny stops working, but you should change that.

Is it possible to create element on the fly with jQuery Mobile?

I have an app built using jQuery (and using various jQuery-UI tools).
For some reason, i have to port it to smartphones/tablet computer, and decided to use jQuery Mobile for that (in order to minimize the number of changes).
In my vanilla app, I created some elements of the page on the fly, depending of user interactions.
For example a slider could be created like that (p is an object with a bunch of params):
function createSlider(p){
return $("<div/>",{
"id":p.id,
"class":p.divClass,
}).slider({
"orientation": p.align,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
"animate":"normal"
/*and some event handling here, but it doesn't matter*/
});
}
And it will produce a nice looking slider. Now it looks like:
function createSlider(p){
return $("<range/>",{
"id":p.id,
"class":p.divClass,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
});
}
But as it's created on the fly, all the stuff done by jQuery Mobile on the page load isn't done on it.
Is there a way to force that initialization without writing the slider in the html?
Thanks.
EDIT: I found in the doc that it could be achieved using container.trigger("create");
However this does not work yet.
EDIT2: Ok create was the solution.
According to the documentation (see edit in the question), using trigger("create") on the containing element works.
And to make that work, you also need to remember that range is an input type and not a tag...
Working solution:
function createSlider(){
return $("<input/>",{
"type":"range",
"id":"sl",
"min":0,
"max":15,
"step":1,
"value":1,
});
}
function appendSlider(){
$("#yourdiv").append(createSlider()).trigger("create");
}
As a sidenote, the documentation for jQuery mobile lacks a search option.
Try calling .page() on the container the content is being added to. Alternatively, adding .page() to the content you're returning may also work.

Where to put custom JavaScript/Prototype code for an ActiveScaffold form?

I have a Select dropdown on the form of an ActiveScaffold. I am trying to hide some of the fields on the form if a particular value is selected.
A [similar question][1] was posted to the ActiveScaffold Google Group, and the supplied Prototype code looks to do what I need, however I don't know where I need to add this.
--
I tried taking a copy of -horizontal-subform-header.html.erb from Vendor/plugins/
active_scaffold/frontends/default/views, placing it in views folder of my controller, and then adding my script into it:
<script type="text/javascript">
document.observe('dom:loaded', function() { //do it once everything's loaded
//grab all the product-input classes and call 'observe' on them :
$$('.product-input').invoke('observe', 'change', function(e) {
this.up('td').next('td').down('input').hide();
});
});
</script>
... but that doesn't seem to work properly. It works if I use a URL to go direct to the form (i.e. http://localhost:3000/sales/20/edit?_method=get). But when I test it with the main list view (i.e. http://localhost:3000/sales/) and opening the form via Ajax, then it doesn't work. Looking at the HTML source the just does not appear.
The common place for adding JavaScript is application.js found in public/javascripts. I'm a jQuery guy myself, however I'm sure you can hook up to the onchange event in application.js with prototype. A quick search looks like Event.observe should do the trick.

Categories

Resources