Jquery cookie always return 1 - javascript

Using the jquery cookie plugin I have a very simple function as so :
demoPopupInit: function() {
// alert($.cookie('modal-popup'));
if (! $.cookie('modal-popup')) {
$.cookie('modal-popup',1) ;
}
if ( $.cookie('modal-popup') <= 3 ) {
// return;
var modal_cookie = $.cookie('modal-popup') ;
modal_cookie = modal_cookie++;
$("#intro_index").modal({backdrop:true});
$.cookie('modal-popup', modal_cookie );
}
},
}
I am sure it is a very simple mistake, but my poor JS skills do not allow me to understand why the alert() in the begining always turn 1..
I also tried
if (! $.cookie('modal-popup') == NULL) {
$.cookie('modal-popup',1) ;
But of course ,the problem is not there , and no other error reported in console.
My aim is to turn the modal pop-up on only on 3 first visits .

Just change post increment to preincrement:
modal_cookie = modal_cookie++;
to
modal_cookie = ++modal_cookie;
Also cookie returns a string value, to be safe use parseInt to compare int value.
and avoid reading cookie multiple times, save it in a varible.
Short:
demoPopupInit: function() {
if (!$.cookie('modal-popup')) {
$.cookie('modal-popup',1) ;
}
var curval = parseInt($.cookie('modal-popup'));
if ( curval <= 3 ) {
// return;
$("#intro_index").modal({backdrop:true});
$.cookie('modal-popup', ++curval);
}
},

Try:
if($.cookie('modal-popup').length < 1){
$.cookie('modal-popup',1);
}
If the cookie doesn't exist, the length will be -1; if it does, it will be 1 or greater.

Related

JavaScript -- Validating a Certain Number of Inputs

I have 8 form inputs that are asking for either 8 half-day activity dates or, 4 fullday dates.
I collected all of the input values and put them into an array, and to test the collection process, wrote the following function that just says if ALL the inputs are empty, keep a button disabled and if ALL are full, enable the button.
function checkMeetings()
{
for(var i = 0; i < meetings.length; i++)
{
if(meetings[i] === "" || meetings[i] === null)
{
meetingsCanSubmit = false;
}
else
{
meetingsCanSubmit = true;
}
}
}
checkMeetings();
That test worked fine.
What I'd like to do is create a counter that counts the number of input boxes that have been filled in and when it gets to at >= 4 enable the button. (In reality it won't enable the button it's going to run a secondary function but for the purposes of this example I'm keeping it simple.)
Since the for loop is counting via the i++ anyways, I tried something to the effect of
if(meetings[i] <= 4) do the following, but that doesn't seem to be doing the trick. Should I be setting up a second counter within my if-statement?
You can use Array.prototype.filter(), check the .length of resulting array
var meetingsCanSubmit = meetings.filter(function(input) {
return input !== "" && input != null
}).length >= 4;
if (meetingsCanSubmit) {
// do stuff
}

Javascript : How can I add X elements to an array

I need to create an array including the first 100 prime numbers, here is my code:
var premier= [];
var nombre= premier.length;
function isPrime(n)
{
if(n < 2)
{
return false;
}
for(i=2; i<Math.sqrt(n); i++)
{
if(n%i===0)
{
return false;
}
}
return true
};
while(nombre<100)
{
var j=2
if(isPrime(j)==true)
{
premier.push(j);
}
j=j+1
}
I am a beginner in Javascript, but I have tested the isPrime function and it works fine even forlarge numbers.
but when I run the program I have:
FATAL ERROR: JS Allocation failed - process out of memory
I think this part is wrong:
while(nombre<100)
{
var j=2
if(isPrime(j)=true)
{
premier.push(j);
}
j=j+1
}
console.log(premier)
But I can't tell why
You are repeatedly setting j=2 every time the loop runs, and you never change nombre so the loop will never end. Note that JavaScript sets literal vaues by value, not by reference, so nombre = premier.length won't magically update.
Additionally, statements of the form if( x = true) will set x to true, and then pass the condition automatically. In this case, since x is a function call, it is invalid syntax.
Did you mean this?
var j = 2;
while(premier.length < 100) {
if( isPrime(j)) premier.push(j);
j++;
}

Unwanted return from JavaScript functions with DOM

I am designing a JavaScript function checkForm(), which is meant to check if at least half of the answers of a form have been completed. It returns ”true” if the condition is met and an alert message and ”false” if not. The answers are given in input text fields, whose content mustn't be the empty string in order to be regarded as answered.
In order to make the check, the function checkForm() calls two other functions: totalNumberOfQuestions() and totalCompletedAnswers(), as follows:
function totalNumberOfQuestions() /* Returns the total number of questions in the form */
{ total
numberOfQuestions = 0;
i = 1;
do
{
nameOfAnswer = 'answer_' + i;
if(document.getElementsByName(nameOfAnswer)[0] != null)
{
totalnumberOfQuestions ++;
}
i++;
}
while (document.getElementsByName(nameOfAnswer)[0] != null);
return totalnumberOfQuestions;
}
function totalCompletedAnswers() /* Returns the total number of completed answers in the form */
{
numberOfCompletedAnswers = 0;
i = 1;
for(i = 1; i<= totalNumberOfQuestions(); i++)
{
nameOfAnswer = 'answer_' + i;
if ( form[nameOfAnswer].value != '')
{
numberOfCompletedAnswers ++;
}
}
return numberOfCompletedAnswers;
}
function checkForm()
{
if ( totalCompletedAnswers() < 7 )
{
alert("Please answer at least half of the questions.");
return false;
}
return true;
}
But, surprisingly, the function checkForm() does not work correctly in this form, but returns true even when the number of completed answers is less than a half of the total number of answers. However, the function works properly if the function totalCompletedAnswers() is checked against a constant value, e.g.:
function checkForm()
{
if ( totalCompletedAnswers() < 7 )
{
alert("Please answer at least half of the questions.");
return false;
}
return true;
}
This means that using the function totalNumberOfQuestions() in the body of the checkForm() function is ”importing” some unwanted returned value. This happens even if I call the former separately (x= totalNumberOfQuestions() and then rewriting the condition: if ( totalCompletedAnswers() < x )
). Does anyone know how one can avoid such unwanted returned values when calling a function?
In totalComletedAnswers you have the snippet:
if(numberOfCompletedAnswers < totalNumberOfQuestions() )
{
alert("Please answer at least half of the questions.");
return false;
}
So totalCompletedAnswers will return false if all the answers are not completed not the number of questions answered.
In checkForm the the following will evaluate to true: false < 7
See: http://jsfiddle.net/5mURZ/
Have a look at these two articles for more information on truthiness/falsiness in javascript:
http://11heavens.com/falsy-and-truthy-in-javascript
http://www.sitepoint.com/javascript-truthy-falsy/
UPDATE
Upon closer inspection you have a scoping issue. All your variables have a global scope. This will cause the most issues with the variable i. Declaring the variable with the var key word will restrict the scope of the variable to the function. It is best practice in javascript to delvare all variable with the var keyword to explicitly declare the scope of the variable.
Working Fiddle: http://jsfiddle.net/Dr5Hx/1/
Article on scoping: http://coding.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/
Update 2
For a completely different approach, try the magic of jQuery. This approach relies on wrapping the answers in some kind of container. In this case a div. This is required as elements such as check boxes and radio buttons would be multiple elements, but each set should only be counted once.
//The selector below finds DOM elements with a name beginning with "answer"
var answers = $("[name^='answer']"); //'Cache' answers
var answerDivs = $("div").has("[name^='answer']"); //'Cache' answer divs
var totalAnswers = answerDivs.length; //'Cache' number of answers
$("#checkIt").click(function(){ //Add a click listener to the button
var numAnswered = $(answerDivs).filter(function(){ //Filter our answer divs to answered question
var answer = $(this).find("[name^='answer']"); //Get the answer element(s) in the div
var textCheck = $(answer).is("input:text") && $(answer).val() != ''; //Check For Text Value
var selCheck = $(answer).is("select") && $(answer).val() != ''; //Check for selected
var radioCheck = $(answer).is(":checked"); // Check for Checked, WOrks for radio & checkbox
//console.log($(answer).attr("name") + " " + textCheck + " " + selCheck + " " + radioCheck)
return (textCheck || selCheck || radioCheck); //End of the filter
}).length;
if(numAnswered < (totalAnswers/2))
{
alert("Please answer atleast half the questions");
return false;
}
alert("We're good to go");
return true;
});
Just make sure to wrap the above in $(document).ready();
http://jsfiddle.net/Dr5Hx/3/

Javascript prev/next buttons populated from database

I'm trying to use javascript for next and previous buttons that cycle through a list of professors in a database. The code I have works except for one bizarre glitch: when there are over 9 professors (for this example there will be 11 professors), clicking the "previou"s button on Prof2 displays Prof1, Prof10, & Prof11 simultaneously.
Similarly, clicking "next" on the last prof, like Prof11 in this example, displays Prof1, Prof10, & Prof11 simultaneously. Can you spot the error? Is there a simpler way to create these buttons? Thank you in advance.
$.vars = {
counter : 2,
limit : $getUnitFacultyPages.TotalItems,
};
function nextItem() {
$('li','#profs')
.fadeOut('slow')
.filter( function() { return this.id.match('profs' + $.vars.counter); })
.fadeIn('slow');
$.vars.counter == $.vars.limit? $.vars.counter = 1 : $.vars.counter++;
}
function prevItem() {
$.vars.counter -= 2;
if($.vars.counter == 1){
$.vars.counter = $.vars.limit;
} else if ($.vars.counter < 0){
$.vars.counter = $.vars.limit -1;
}
nextItem();
}
$("#profs-next").click(function () {
nextItem();
});
$("#profs-prev").click(function () {
prevItem();
});
One thing that stands out is use of match that would "match" the regular expression and would cause the behavior that you describe. This should be changed the equality.
return this.id.match('profs' + $.vars.counter);
should be
return this.id == 'profs' + $.vars.counter;
There could be other things as well.
Not sure whether or not this will solve your problem, but there are a couple things that look a little suspect to me at a glance:
Why do you decrement by 2?
You're checking if $.vars.counter == 1 or $.vars.counter < 0. What happens if $.vars.counter == 0?
Edit:
Also, your prev/next logic is a little strange (imo). Ignoring your display logic, I might change it to:
$.vars = {
idx: 0,
limit: 5,
};
function nextItem()
{
$.vars.idx = $.vars.idx >= $.vars.limit ? 0 : ++$.vars.idx;
}
function prevItem()
{
$.vars.idx = $.vars.idx <= 0 ? $.vars.limit : --$.vars.idx;
}

CSS - js rendering links useless

Ok, well, thanks to people here, I figured out the portion of my js code that's rendering my links useless is what's pasted below... Still trying to figure out why, but if someone has any insight, that'd be great...
function initJumpMenus() {
// Turns all <select> elements with the 'jumpmenu' class into jump menus
var selectElements = document.getElementsByTagName("select");
for( i = 0; i < selectElements.length; i++ ) {
// Check for the class and make sure the element has an ID
if( selectElements[i].className == "jumpmenu" &&
document.getElementById(selectElements[i].id) != ""
) {
jumpmenu = document.getElementById(selectElements[i].id);
jumpmenu.onchange = function() {
if( this.options[this.selectedIndex].value != '' ) {
// Redirect
location.href=this.options[this.selectedIndex].value;
}
}
}
}
}
window.onload = function() {
initJumpMenus();
}
This:
document.getElementById(selectElements[i].id) != ""
is wrong. You want to check if the element has an id, so simply do:
selectElements[i].id != ""
I'd like to point out that you can improve your code here and there:
1 Don't write for loops that get the length property for each iteration,
instead do:
for( i = 0, num = selectElements.length; i < num; i++ ) {
...
}
Only if you expect selectElements to grow or shrink it would make sense to requery the property value, but in that case, you probably should not write a for loop anyway.
2: Don't write nodelist[index]
For nodelists, such as returned by getElementsByTagName() you should not write nodelist[index] (even though most browser support that). The standard DOM method is item, so write nodelist.item(index) instead.
3 fetch items from the list only once
If you need an item from the list more than once, store it in a local variable. your loop would become:
for( i = 0, selectElement; i < selectElements.length; i++ ) {
selectElement = selectElements.item(i);
...more code using selectElement...
}
Note the declaration of the selectElement variable in the for loop. since you don't use it outside the loop, declaring it there avoids clutter and ensures that if you move the loop, you move the declaration.
4. cheapest comparisons first
You wrote:
selectElement.className == "jumpmenu" &&
selectElement.id != ""
this could be slightly improved if you reverse the legs:
selectElement.id != "" &&
selectElement.className == "jumpmenu"
This will be faster, since it is less work to check if a string is empty, and for those cases where the string is empty, we won't even check the className
5 Don't use document.getElementById() if you already have the element
Inside the loop you have this:
jumpmenu = document.getElementById(selectElements[i].id);
You are basically getting the id from the selectElement and use that to query the document to find ....the element having and id equal to that of the current selectElement. Becuase id's are unique within the document (or should be), you are basically writing a completely unecessary sentence. jumpmenu and selectElement refer to one and the same object.
6. onchange handler improvements
inside the loop you assign an onchange handler. you do so by creating a new function for each loop iteration. This is the handler code:
function() {
if( this.options[this.selectedIndex].value != '' ) {
// Redirect
location.href=this.options[this.selectedIndex].value;
}
}
Three things are of note here: First, the onchange handler code contains this location.href = ... that should probably be document.location.href = ....
Second, you refer twice to this.options[this.selectedIndex].value. Again, put this in a local variable.
Third, the this refers to the element that experienced the onchange event by the time this function is executing. Other than this and properties of this, there are no variables in this handler that originate from the loop or the outer initJumpMenus function. You should simply create it once, outside the loop, and assign it every iteration:
var onchange_handler = function() {
if( this.options[this.selectedIndex].value != "" ) {
// Redirect
location.href=this.options[this.selectedIndex].value;
}
}
for (...) {
if (...) {
selectElement.onchange = onchange_handler;
}
}
7 Summary
Putting it all toghether, this is how I would write it:
function initJumpMenus() {
var handler = function() {
var value = this.options.item(this.selectedIndex).value;
if( value != "" ) {
// Redirect
document.location.href = value;
}
}
var selectElements = document.getElementsByTagName("select");
for(var i = 0, num = selectElements.length, selectElement; i < num; i++ ) {
selectElement = selectElements.item(i);
// Check for the class and make sure the element has an ID
if( selectElement.id != "" &&
selectElement.className == "jumpmenu"
) {
selectElement.onchange = handler;
}
}
}
Check the error console; any exception in the JS will stop the links form reacting to a click.

Categories