show json file in an alert on click - javascript

I have a simple log in at the top of my page that enables a user to enter a code - the code then reads the json file and pulls up the specific user of that code. I do have it showing in the alert, however I want the alert hidden before the user enters the code and displayed if the code is valid. In my json file I have the users code (which is currently named id) and when that is entered their name displays in the alert box. If nothing or an invalid code that is not apart of my code display I want an error alert to display.
This is what I have so far:
the log in text button:
<div class="alert alert-info"><input type="text" id="userName" value> <button type="button" id="loginbtn" class="btn btn-primary btn-md">Login</button></div>
the welcome/login alert:
<div class="alert alert-success" id="loginalert"<strong>Welcome</strong></div>
the error alert:
<div class="alert alert-danger" id="ErrorMessageAlert" <strong>Error</strong>invalid</div>
and the script ive been working on:
$(document).ready(function() {
$("#loginalert").hide();
$("#ErrorMessageAlert").hide();
$("#loginbtn").click(function(event){
$.getJSON('result.json', function(jd) {
var id = $('#userName').val();
for (var i=0; i<jd.user.length; i++) {
if (jd.user[i].ID == id) {
$('#loginalert').html('<p> Welcome: ' + jd.user[i].name + '</p>');
$("#loginalert").show();
}else
{
$("#ErrorMessageAlert").show();
}
);
}
}
});
}); });
A user from the json looks like {"user":[{"ID" : "001","name": "Zara Ali"}
So when the user writes in 001 the alert will display with that name
If the user enters nothing or an invalid code I want the error message to display.
Many thanks

I believe it would be easier to simply use ajax to get the JSON, as it makes your code more readable - that, and indentation and line breaks. The below should work but cannot be tested on Stack Overflow itself as it does not allow AJAX requests. The reason to use this piece of jQuery is that it has some neat built-in features and since this looks like it might be a login form, you might want to post some data over the web as well, which gets easier for later with ajax.
$(document).ready(function(){
$('#loginalert, #ErrorMessageAlert').hide();
$("#loginbtn").click(function(event){
// Every time you click the button, hide all alerts again
$('#loginalert, #ErrorMessageAlert').hide();
$.ajax({
url: 'result.json',
success: function(msg){
for(var i = 0; i < msg.user.length; i++){
if(msg.user[i].ID == id){
$('#loginalert')
.html('<p> Welcome: ' + msg.user[i].name + '</p>')
.show();
} else {
$('#ErrorMessageAlert').show();
}
}
},
error: function(e){
$('#ErrorMessageAlert').show();
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alert alert-info">
<input type="text" id="userName" value>
<button type="button" id="loginbtn" class="btn btn-primary btn-md">Login</button>
</div>
<div class="alert alert-success" id="loginalert"<strong>Welcome</strong></div>
<div class="alert alert-danger" id="ErrorMessageAlert" <strong>Error</strong>invalid</div>
There also seems to be a bit of a problem here in logic - can you have multiple users logged in at once in the same place? If not, then why are we looping through the results? You should return just one user, not nested. If you now get back multiple users, then only the last users name will be displayed, and that's odd. I would either change your JSOn to return only one user by default, or modify the javascript to only check for one:
success: function(msg){
if(msg.user[0] && msg.user[0].ID == id){
$('#loginalert').html('<p> Welcome: ' + msg.user[0].name + '</p>').show();
} else {
$('#ErrorMessageAlert').show();
}
}
The major thing is structure, though. Use tabs, line-breaks, and any kind of visual information to show what step nests in what other step, making your code easier to read at a glance.

Related

How to change the contents of the modal through javascript function?

Hi I am making Quiz module. In which student can take quiz. once submitted, if the quiz is not passed, than students can 'retake quiz'. Once students click on 'retake quiz', only questions for which user gave wrong answer will be showed up. I am using php and HTML modal for showing the questions for the first time when student take quiz. Than using jquery and javascript, I am passing the responses of user to backend and checking if it is passed or failed. If failed, than I have wrong questions id, whihc I want to display when they take 'requiz'. Following a code:
Index.php
//When user clicks this button, modal will be pop-up and questions will be displayed one by one.
Start Quiz
<!-- Quiz Modal -->
<div class="modal fade quiz-modal" id="Quiz">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<? foreach ($questions as $i=>$question) { ?>
<div class='question'>
<div class="modal-header">
<div class="row">
<h4>QUIZ</h4>
</div>
</div>
<div class="modal-body">
<div class="row">
<div id="quest-content" class="quest">
<h4 class="question-title"><?=$question->number?>) <?=$question->title?></h4>
<ul class="list-unstyled">
<? foreach ($question->getAnswers() as $answer) { ?>
<li>
<div class="checkbox">
<input class="cb" type="checkbox" name="answer[]" value="<?=$answer->title?>">
<?=$answer->title?>
</div>
</li>
<? } ?>
</ul>
<br>
<br>
<p class='error'>Please select an answer</p>
</div>
</div>
</div>
<div class="modal-footer">
<p class='quest_num'><?=$question->number?> of <?=count($questions)?></p>
<? if( count($questions) === 1 ) { ?>
<a class="btn button btn-lg quiz-btn">Submit Quiz</a>
<? } else if ( count($questions) === $i +1 ) { ?>
<a class="btn button btn-lg quiz-btn">Submit Quiz</a>
<? } else { ?>
Next Question
<? } ?>
</div>
</div>
<? } ?>
</div>
</div>
</div>
Following is <script> where I am doing couple of things: if there are more questions, button will show 'Next' and if it's a last question- button will show 'Submit'. Once submit the quiz, it will send user's responses to backend through $.post and get back the array of questions IDs that were wrong. Using this wrong question's ids, when user clicks on 'Retake Quiz', it should show quiz again with these ids only.
<script type="text/javascript">
$(document).on('ready', function(){
var answers = [];
$('.quiz-btn').click(function(e){
e.preventDefault()
var checkbox = $(this).parents('.question').children('.modal-body').children('.row').children('.quest').children('ul').children('li').children('.checkbox').children('.icheckbox_square');
var btn = $(this).parents('.question').children('.modal-footer').children('.quiz-btn')
var next = false
var submit = false
console.log(checkbox)
$(checkbox).each(function(){
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($(this).children('.cb:checked').val());
console.log(answers);
next = true
}
else if ($(this).hasClass('checked') && $(btn).html() == 'Submit Quiz') {
answers.push($(this).children('.cb:checked').val());
submit = true
}
});
if ( next ) {
e.preventDefault();
$(this).parents('.question').slideUp(500);
$(this).parents('.question').next('.question').delay(500).slideDown(500);
} else if ( submit ) {
e.preventDefault();
$.post('/student/submit_quiz',{answers: answers, module: <?=$model->course_module->id?>}, function(data){
var correct = data['correct'];
var incorrect = data['incorrect'];
if(incorrect){
if(incorrect.length > 0){
var div = $('.quest')[$('.quest').length - 1];
var footer = $('.modal-footer')[$('.modal-footer').length - 1];
var progress = (correct.length*100)/(<?=count($questions)?>);
div.innerHTML = "<h4 class='question-title'>" + (correct.length)+"/<?=count($questions)?> questions correct <h4>";
div.innerHTML += "<div class='error'><p><strong>We are sorry but you have " + incorrect.length +" answers incorrect</strong><br>Please go back and review and reanswer those questions.</p></div>";
footer.innerHTML = "<a onclick='retakeQuiz(["+incorrect+"])' class='btn btn-success btn-lg quiz-btn'>Retake Quiz</a>";
} else {
var div = $('.quest')[$('.quest').length - 1];
var footer = $('.modal-footer')[$('.modal-footer').length - 1];
var progress = (correct.length*100)/(<?=count($questions)?>);
div.innerHTML = "<h4 class='question-title'> Congratulations!! You Passed this Module.<h4>";
footer.innerHTML = "<a href='/student/course/<?=$model->course->id?>' class='btn btn-default btn-lg'>Continue</a>";
}
}
});
} else {
console.log(next)
$('.quest .error').fadeIn();
}
});
});
function retakeQuiz(incorrect) {
$.each(incorrect, function(key, val) {
alert('index ' + key + ' points to file ' + val);
//Here incorrect is the array of Wrong Question's IDs. How can I use that id to show only this questions in my above modal.
});
}
</script>
I would like to know you all that I have only one Modal- that shows the quiz questions one after another and when quiz is completed and user submit the quiz, it will show the message of pass or fail along with the respective button say 'Continue' or 'Retake Quiz'. If 'Retake Quiz' is clicked, wrong questions will be displayed on the modal. So I have only one modal, but just changing the contents dynamically through javascript.
I tried my best to explain my question and code. Hope to get some help. Help is highly appreciated.
Doing manipulating from two sides like this always ends up in a bit of a tizy. Instead of changing the questions by using jQuery, can you change your PHP endpoint to return modal content given a set of ids? Here is the big idea:
Your PHP code has an endpoint that takes in a list of ids. These ids get passed off to the PHP code which does it thing and returns a list of questions of the ids (and corresponding answers). When a user first visits your page, your PHP code auto-loads all of the questions into the modal so the user gets the entire quiz (similarly to how you are loading on initial page load now).
Once they finish the quiz, you said you stored the ids of the questions they got wrong. What I would recommend is sending the ids to your php code to return a newly generated modal only including the ids of questions they got wrong. Then, you can simply replace the modal content with the result. Something like this perhaps (this is all psuedo-code, but I hope it gets the idea across)
// user has finished taking the quiz
$.get({
"url": "/yourendpoint" + ids.toString()
"method": "GET"
}.then(function(data){
$(".modal-content").html(data);
});
My suggestion is to add attribute id to the every question divison with the value of question id like below
<? foreach ($questions as $i=>$question) { ?>
<div class='question' id="<? $question->id ?>">
// Your remaining code here
</div>
<? } ?>
After submitting the form, in your callback of ajax call, remove the question divs with the ids those are not present in the response like below
function retakeQuiz(incorrect) {
// I am assuming incorrect as [id, id, id] for example
$('.question').each(function (index, question) {
if (!incorrect.includes($(question).attr('id'))) {
$(question).remove();
}
});
}

Ajax request stores old data

I have a litte problem with my ajax request and I haven't found a solution yet.
What I am trying to accomplish:
I have simple search form, when I submit I send the data to a PHP file which returns the result as json. Then I add the returned data in a clickable list and when I click on one list item I want to display the data in a new div. This actually works fine. Even if I start a new search I get the correct json objects and the list updates as expected but now I have following problem. If I start a new search without refreshing the whole page and again click on a list item, in the console log i see that the new but also the previous data is still kinda stored in the list or wherever and this is the problem because I then display the wrong data if I click on the list items.
I hope you understand my question and I am thankful for every hint. And btw, is my approach even possible or is there a better way to solve this?
Javascript code
$('#searchbar').submit(function(e){
e.preventDefault();
var query = $('#searchQuery').val();
if (query != ''){
loadData();
}else{
alert('Empty searchform!');
}
});
function loadData(){
var query = $('#searchQuery').val();
$.ajax({
type: "POST",
url: "search.php",
data: {'query': query},
dataType: 'json'
}).done(function(res) {
console.log(res);
resetInfos();
generateList(res);
$('.list-group').on('click', '.list-group-item', function(e){
var index = $(this).index();
console.log(res[index].Name);
$('#locationName').text(res[index].Name);
$('#locationAddress').text(res[index].Zip
+ ' '
+ res[index].State);
$('#locationContact').text(res[index].Internet);
init_map(res[index].Latitude, res[index].Longitude);
});
});
}
function resetInfos(){
$('.list-group').empty();
$('#listItems').remove();
$('#searchQuery').val('');
$('#locationName').text('');
$('#locationAddress').text('');
$('#locationContact').text('');
}
function generateList(result){
$.each(result, function(i){
$('.list-group').append('<li class="list-group-item" id="listItems">'
+ result[i].Name
+ ", "
+ result[i].Zip
+ " "
+ result[i].State);
});
}
HTML search form
<form id="searchbar">
<div class="input-group form-group-lg">
<input type="text" id="searchQuery" name="query" class="form-control" autocomplete="off" placeholder="Name, ZIP, State">
<span class="input-group-btn"><button class="btn btn-success btn-lg" id="searchButton" type="submit">Search</button></span>
</div>
<form>
Ok I solved it. I had to remove the click event handler with
$('.list-group').off('click');
in my resetInfos function.
You are using id selector to remove multiple elements.
$('#listItems').remove();
It will only remove the first matched reference. Please add some class to li element and then use class selector to remove.

jquery and php counting number of clicks and post the results in another page

<p>which color do you prefer?</p>
<button type="button" id="redButton" value="Red"/>
<button type="button" id="greenButton" value="Green"/>
<button type="button" id="blueButton" value="Blue"/>
<p>Red => <span> 0 </span></p>
<p>Green => <span> 0 </span></p>
<p>Blue => <span> 0 </span></p>
I'm trying to make a form with a question like:
Which color do you prefer?
(The buttons in a question.html
and the result in result.html)
And buttons which can be clicked to answer (red, green, blue).
On another page I want to take this data and want to check how many times each button was clicked and post it (in a way - red -
3 clicks and so on).
I want to do it with jQuery and PHP - and honestly I don't know much
about php. Can any one please help me?
As you can see from the votes, this type of question doesn't really fit well here at SO. We generally expect that you have code showing what you have tried so far and are asking for help with a specific issue you are facing.
That said, if I were you, I would use parse.com's services which will let you do this with just javascript.
Here is a post that will explain what you'd need to do to get setup with parse.
Here is a working jsFiddle showing how to save the votes
Code from that demo:
<input type="button" value="Red" class="vote"/>
<input type="button" value="Green" class="vote"/>
<input type="button" value="Blue" class="vote"/><br><br>
<div id="link"></div>
Parse.initialize("Application ID", "JavaScript key");
$('.vote').click(function(){
// create the `Parse` object
var ColorVote = Parse.Object.extend("ColorVote");
var _colorVote = new ColorVote();
// set the object's value to our button value
_colorVote.set("color", $(this).val());
// save the object
_colorVote.save(null, {
success: function(_colorVote) {
// if the save succeeded, give link to view results
$('#link').html('Vote saved! Please click here here to see the results of the vote so far.')
},
error: function(_colorVote, error) {
// save failed, do error handeling here
console.log('Failed to create new object, with error code: ' + error.message);
}
});
});
Here is a working jsFiddle showing how to display the saved votes
Code from that demo:
<div id="results"></div>
Parse.initialize("Application ID", "JavaScript key");
// create a query to search for our `ColorVote` items
var ColorVote = Parse.Object.extend("ColorVote");
var query = new Parse.Query(ColorVote);
query.limit(1000);
query.find({
success: function (results) {
var red =0, green =0, blue =0;
$.each(results, function(i,e){
if(e.get('color')=='Blue') blue++;
else if(e.get('color')=='Green') green++;
else if(e.get('color')=='Red') red++;
});
$('#results').html('Blue - '+blue+'<br>'+'Green - '+green+'<br>'+'Red - '+red+'<br>');
},
error: function (error) {
console.log("Error: " + error.code + " " + error.message);
}
});

How to dynamically show error messages through PHP

I am creating a PHP login script. So far I have only worked on the registration.
My question is, how can I handle validation in PHP without refreshing the page? I want to output the feedback that the user has entered information wrongly, but I don't want to refresh the page. This is because I am using AJAX, so I want it to output on the page.
Is this possible?
See here, if you "sign up" without filling in any of the boxes it shows you some error messages. The problem is that it reloads the page as it does it. Is there a way to not reload the page and still show this data?
http://marmiteontoast.co.uk/fyp/login-register/test/index.php
This is an example of the if statement for just the username. This is repeated with all the other fields too:
if(isset($_POST['username'])){
$username = mysql_real_escape_string(trim($_POST['username']));
if(strlen($username) > 3){
// passed
if(strlen($username) < 31){
// passed
} else {
$_SESSION['status']['register']['error'][] = 'The Username is greater than 30 characters.';
}
} else {
$_SESSION['status']['register']['error'][] = 'The username is less than 4 characters.';
}
} else {
$_SESSION['status']['register']['error'][] = 'The Username is not entered.';
}
Once it passes all the validation it does:
header('Location:index.php');
And the errors are output on the index page by:
<?php
if(isset($_SESSION['status']['register']['error'])){
?>
<div class="alert alert-error">
<p><strong>There's a problem!</strong><br /><br />
<?php
foreach($_SESSION['status']['register']['error'] as $error){
// Outputs list of all errors, breaks to new line
echo $error . '<br />';
}
?>
</p>
1. Is it possible to output these dynamically with PHP?
2. Could I do the validation on the front end, then just pass it to the PHP to pass to the database?
2a. How would I handle running a username exists check if I do it front end?
This is something I actually just made the other day!
I have a file called "register.js", a file called "register_process.php" and some html.
How my server is set up:
html_docs (www):
ajax:
register_process.php
js:
register.js
jquery-1.6.2.js
register.html
so within my register.html, my code looks like such:
<script type="text/javascript" src="js/md5.js"></script> <!-- this is in my head -->
<script type="text/javascript" src="js/jquery-1.6.2.js"></script>
<!-- everything else is in my body -->
<div id="error_message" style="display: none;">
</div>
<div id="register_div">
<input type="text" name="username" id="username"><br>
<input type="password" name="password" id="password"><br>
<input type="submit" name="submitbutton" id="reg_button" value="Register" onclick="AttemptRegisterAjax(); return false;"><br>
</div>
This calls the function inside of my register.js file. That functions looks like such:
function AttemptAjaxRegister(){
var url = "ajax/register_process.php?";
url += "time=" + (new Date().getTime()) + "&un=";
var username_ele = document.getElementById("reg_username");
var password_ele = document.getElementById("reg_password");
var error_ele = document.getElementById("error_message");
var username = username_ele.value;
var password = password_ele.value;
if((username.length >=4) && (password.length >= 4)){
url += encodeURIComponent(username) + "&pw=" + encodeURIComponent(password);
console.log(url);
$.get(url, function(data, status, xhr){
data = data.trim();
if(data != "true"){
error_ele.innerText = data;
error_ele.style = "display: block;";
}else{
window.location = "/profile.php";
}
});
}else{
error_ele.innerText = "Please make sure your password and username are both 4 characters long";
error_ele.style = "display: block;";
}
}
now, inside of your php, you'll want to set everything up just like how you had it to register, but you'll want to actually just call die($YourErrorMessage); or if the registration was successful, die("true");
Not directly, you will need to use another tool for that, most likely Javascript.
Yes but that would be a terible practice. the best way to validate on both.
2a. I believe you would need to use a database.
thsi tutorials might help you out.
Easy jQuery Ajax PHP Contact Form
How to create a Sign Up form registration with PHP and MySQL

JQuery Ajax call stop refresing the page

I have the following html code:
<div>
<form id="ChartsForm">
<div id="optionsheader">
<p>Choose your page:</p>
<div id="dateoptions">
<p>Until date: <input type="date" name="until_date" value="Until date"></p>
<p>Since date: <input type="date" name="since_date" value="Since date"></p>
</div>
</div>
<select name="accmenu" id="accmenu" style="width:300px; float:left; clear:both;">
<?php
$user_accounts = $facebook->api('/me/accounts','GET');
foreach($user_accounts['data'] as $account) {
?>
<option data-description="<?php echo $account['category'] ?>" data-image="https://graph.facebook.com/<?php echo $account['id']; ?>/picture" value="<?php echo $account['id'] ?>"><?php echo $account['name'] ?></options>
<?php
}
?>
</select>
<div class="insightsoptions">
<p>Choose your insights:</p>
<input id="newLikes" class="insightsbuttons" type="submit" name="submit" value="Daily new likes">
<input id="unlikes" class="insightsbuttons" type="submit" name="submit" value="Daily unlikes">
</div>
<div class="insightsgraphs">
<div id="dailyNewLikes"></div>
<div id="dailyUnlikes"></div>
</div>
</form>
</div>
which has a form with the id=ChartForm that contain two date inputs until_date and since_date, one select accmenu and two submit inputs with the values Daily new likes and Daily unlikes. I use the following Jquery function:
$(function () {
$('#accmenu').change(function() {
$(".insightsgraphs div").hide();
$(".insightsoptions input").attr("class","insightsbuttons");
});
$("#newLikes").one('click', function () {
$.ajax({type:'GET', url: 'newLikes.php', data:$('#ChartsForm').serialize(), success:
function(response) {
var json = response.replace(/"/g,'');
json = "[" + json + "]";
json = json.replace(/'/g,'"');
var myData = JSON.parse(json);
var myChart = new JSChart('dailyNewLikes', 'line');
myChart.setDataArray(myData);
myChart.setSize(960, 320);
myChart.setAxisNameX('');
myChart.setAxisValuesColorX('#FFFFFF');
myChart.setAxisNameY('');
myChart.setTitle('Daily New Likes');
myChart.draw();
}});
return false;
});
$("#newLikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyNewLikes').toggle();
});
$("#unlikes").one('click', function () {
$.ajax({type:'GET', url: 'unlikes.php', data:$('#ChartsForm').serialize(), success:
function(response) {
alert(response);
$("#dailyUnlikes").html(response);
}});
return false;
});
$("#unlikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyUnlikes').toggle();
});
});
for the application flow in the following manner: every time I click on one of the input submit buttons the script will make only one Ajax GET request to a specific php file that send me back a response with which I create a Chart in a hidden div with the id=dailyNewLikes or id=dailyUnlikes by case (for testing purposes I work for the moment only on the first button). The button it will change his background color into green and the div it will be shown. I use $("#newLikes").on('click', function(){ for change back and forth the background color and the display time of the div. (from green and display:block to red and display:none, you get the point I hope :D). Also I use $('#accmenu').change(function() { to change all buttons to red and hide the respective div in case an option from the select is changed. My problem is that after I refresh the page (Ctrl+R) choose since and until date, click on the first button (it change to green and the div is shown, also the toggle is working fine) and then click on the second button which works fine on the first click (is becoming green and div is shown) but on the second click I have an issue: the script is making another Ajax GET request (a wrong URL one) and the page is refreshed. Ex. of a good reguest URL:
http://localhost/smd/unlikes.php?until_date=2013-05-01&since_date=2013-04-01&accmenu=497232410336701
and an ex. of a wrong request URL:
http://localhost/smd/?until_date=2013-05-01&since_date=2013-04-01&accmenu=497232410336701&submit=Daily+unlikes#_=_
Like it can be seen (it doesn't need in the first to make this extra request) the php file is not present and also a new submit parameters is added. This also happen if I change from the select with another option. What am I do wrong? I really need to know, not just to have my code "fixed". It bugging me for a little while. Any feedback is more than welcomed. P.S. Also, how can I start the .one function only if both date inputs has been choosen? Something like how could help me?
var until = $('#dateoptions input[name="until_date"]').val();
var since = $('#dateoptions input[name="since_date"]').val();
if (until == "" || since == "") {
alert('Until date or Since date missing!');
return;
}
it will work that way? Sorry for the long question...
i think you should make your question a little shorter and just point what you need and what errors are you getting ..anyways...going through your code i see you have two click event for same button at the end for $("#unlikes").one and $("#unlikes").on(..and no return false in other function.
try adding return false
$("#newLikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyNewLikes').toggle();
return false;
});
$("#unlikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyUnlikes').toggle();
return false;
});
my guess is that , since you have two click event..when it gets clicked ..these event will fire and since you are missing return false in second click function...the form gets submitted hence refreshing the form.
however its better if put your codes in single click function than creating two seperate click event.

Categories

Resources