I've been creating a web app and one example of something it does is create golf rounds. Everything I've done works but I have been doing some testing and the way im passing variables through to my ajax call means the user could update anyone's round.
Currently I have a table that shows you your round and you can select the view button which will open a modal form to show details of that round.
This is my HTML
<button
type="button"
id="view-round"
class="btn btn-outline-primary btn-square btn-skew pull-right"
attr-id="39"
>View</button>
This is my jquery
$('body').on('click', '#view-round', function () {
var id = $(this).attr('attr-id');
$.post('/dashboard/pages/golf/round/ajax.php?action=load', {id: id}, function(response) {
//code in here
}
});
You can see from this that I'm passing through the round id via the attribute on the button "attr-id".
What I'm asking is can I put this variable somewhere someone couldn't edit it via the developer console etc.
I'm currently changing the ajax calls so that you can only update/look at your own records but really I'd like to stop it from being changed all together.
Related
I'm trying to write a feature for my Fantasy Football league that allows players to trade with each other. Functionally it all works fine, but as I've coded it all in PHP I have an annoying problem where any time a button is pressed the page is effectively refreshed twice. I've read that I can get around this with jQuery and Ajax but sadly I don't really have any experience with either.
Here's a small section of the code that allows logged in users to withdraw a trade offer they have made:
echo "<input type='submit' id='btn-danger' name='withdraw".$trade_id."' value='Withdraw'>";
if($_POST && isset($_POST['withdraw'.$trade_id])) {
$withdraw = $link->prepare("DELETE FROM trade_id_offers_out WHERE trade_id_offer_id = ".$trade_id);
$withdraw->execute();
}
This creates a "Withdraw" button for each trade offer they have sent out and has a unique name of "withdraw" plus whatever number the offer is in the SQL table.
As I say functionally it works perfectly fine. But it refreshes the page twice and I'm wondering how I can take this code and turn it into something a little more practical?
Many thanks for your time.
First you should make sure you have included jQuery into your page html before any other jQuery (there are plenty of tutorials out there).
Second you need to give the submit button a class so you can select it using a jQuery selector. Change the php code of the button to this:
echo "<input type='submit' id='btn-danger' class='withdrawTradeBtn' name='withdraw".$trade_id."' value='Withdraw'>";
Finally you would make a ajax post request to your url (same url as your page in this case). The js would look something like this and would need to be placed before the end of the html body tag or after all your buttons are rendered:
(Note: I have not tested this but it should be pretty close to what you are after)
<script>
//we need to wait for the page to be loaded in the users browser
$(document).ready(function(){
//we are selecting all the buttons with the class withdrawTradeBtn
//we are binding to the click event so whenever any of the buttons are pressed the code will be ran.
$('.withdrawTradeBtn').on('click', function(e){
//we need to prevent the button from actually reloading the page
e.preventDefault();
//now we need to make a ajax post request to the url
$.post(
'/your/url', //the url to make the post
{$(this).attr('name'):'Withdraw'}, //the submitted data
function(data, status, jqXHR) {// success callback
//here is were you would delete the button or whatever
}
);
});
});
</script>
Most likely you would want to delete the trade entry from the html. You would do that in the success callback of the ajax post. I cant really add anything here because I don't know what your html structure looks like.
Hope this helps, let me know if you need any more help!
I'm trying to make a button that when it's being a click, it will trigger a click for another button too but with a delay for each of them. For example, if the Main Button is clicked, the Sub Button 1 will trigger a click, then Sub Button 2 will be clicked after 2 seconds and the Sub Button 3 will be clicked after 4 seconds.
The real scenario is a customer can select up to 3 products, the 3 products will be added to a cart if they click the main button because the add to cart button of those 3 products will be clicked too as they click the main button. The products page has an Ajax. If I click the main button, sometimes only 1 or 2 product(s) are being added. I'm trying to delay a click for each button.
$(".main-button").on("click",function(){
$(".container .row").each(function(i){
$rowNum = $(this).attr("id","row-" + i);
$rowNum.find("button").trigger("click").delay(5000).text("clicked");
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="main-button">Main Button</button>
<div class="container">
<div class="row">
<button class="sub-button">Sub Button 1</button>
</div>
<div class="row">
<button class="sub-button">Sub Button 2</button>
</div>
<div class="row">
<button class="sub-button">Sub Button 3</button>
</div>
</div>
$(".main-button").on("click",function(){
myLoop ($(".container .row").children().length)
});
var i = 1;
function myLoop (count) {
setTimeout(function () {
$('.container :nth-child('+i+')').children('button').text("clicked")
if (i < count) {
i++
myLoop(count);
}
}, 1000)
}
Try demo -
https://jsfiddle.net/jijomonkmgm/oL3bzp5r/
This isn't specifically what you asked for, but the outcome of the functionality that you seek will be the same.
In the comments, others and myself, talked about how you could choose to call your sub button functions within the main function itself, without having the logic of a chained button clicking functionality.
Before you can do that, you need to make sure that all of your sub functions are within the global scope so that you can access them in your main function.
Example:
subButtonOneFunction() {
//do something
}
subButtonTwoFunction() {
//do something
}
subButtonThreeFunction() {
//do something
}
$(".main-button").on("click",function(){
$.ajax({
type: 'POST',
url: '/path/to/your_page.php',
data: {
data : dataVar,
moreData : moreDataVar
},
success: function (html) {
subButtonOneFunction();
subButtonTwoFunction();
subButtonThreeFunction();
//and so forth
}
})
});
The sub button functions in this example is within reach of the main function, and so you will be able to call the sub functions within the main function.
Not knowing if there is more to your main function, other than the delayed, button clicking loop that you were attempting, I tried to provide an example of how an AJAX function works, plus adding a success function where you can call your sub functions.
Firstly, we declare the type. The type is the data type for the data the AJAX function will parse. Notable data types are POST and GET.
Secondly, we declare the url. The url is the page where your data will be parsed to. It can be your current page, or another page entirely.
Thirdly, we declare our variable names for our data that we wish to parse, and what their content is. The variables go by the same logic as any other variables that you know from JavaScript. So they can contain numbers, strings, arrays, whatever you normally know.
Taking one of the data variables from the AJAX example and giving it a value could be done like this:
Our AJAX example: data : dataVar
Literal example: data : $('input#SomeInputContainingValue').val()
our AJAX variable data will now contain the value of an input field that has the id SomeInputContainingValue.
Another example using the clicked elements value: data : $(this).val()
As you can see, the data is simply variables that you would declare as any other JavaScript variable. The difference here is that : is basically the syntax for = in the AJAX function's data array.
Lastly, we declare our success function in the AJAX function. What this does, is that it allows us to "do something" upon success. This is where you can call your sub functions for instance.
This would be a much cleaner approach, and will be much easier to look through when going over the application in the future, and doesn't look like a "hack" or other workarounds.
I have a button that I'm using to submit a form (quiz). I also have another button to do this, but it gets built dynamically. Note the workflow of the code below.
Ultimately, I want PHP to know which button was pressed to submit the form. So, I included name="save_progress" in the <button> code below. However, including that automatically submits the form and bypasses the setTimeout() in my javascript. Removing it makes the setTimeout() function properly, but I don't get the save_progress data via $_POST.
Button...
<button class="btn btn-primary btn-block btn-lg" name="save_progress" onclick="save_progress(); return false;">Save Progress</button>
Javascript...
//For saving quiz progress
function save_progress(){
$('#save_progress_submit_container').modal('show');
setTimeout(function() {
submit_quiz();
}, 1000);
}
//Submitting a quiz
function submit_quiz(){
$("#answers").submit();
}
Any ideas that will work with this workflow? I've already reviewed this (How can I tell which button was clicked in a PHP form submit?) and it doesn't apply here, unfortunately.
Came up with a better solution overall. I created <input type="hidden" id="submit_type" name="submit_type" value=""> in the form, then simply updated the value using jQuery based on which button was clicked.
For future readers, #Niloct's link in the comments caused me to get a save_progress() is not a function error, but it did prevent the submission.
Previous question for context: C# MVC 5 Razor: Updating a partial view with Ajax fails
Now that I have successfully managed to refresh my partial view, I find myself having another difficulty which I don't really know how to deal with. You see, the table I am displaying also displays two buttons per line:
<td class="noWrap width1percent tri">
<input type="button" value="Valider" id="Valider_#i" data-valid=data />
<input type="button" value="Rejeter" id="Rejeter_#i" data-reject=data />
</td>
That's a "validate" button and a "rejection" button. Basically, each line can either be "approved" or "rejected", and the user uses those buttons to make a decision for each line. The actions are bound to a Javascript script, put on top of the main view, which looks like this:
$(function () {
$('*[data-valid]')
.click(function () {
// Get values of fields
$("#divLoading").show();
var idOfField = this.id;
var data = document.getElementById(idOfField).dataset.valid;
// Partially censored code
// Now that we have the values of all fields we need to use a confirmation message
var result = confirm("OK?")
if (result == true) {
// The user chose to validate the data. We have to treat it.
validateResults(data);
}
else {
$("#divLoading").hide();
}
})
ValidateResults:
function validateResults(data) {
$.ajax({
url: '#Url.Action("ValidateControl", "Article")',
type: "POST",
data: { data:data},
success: function (result) {
$("#tableControl").html(result);
$("#divLoading").hide();
}
});
}
A similar function exists for the rejection button.
Now, before successfully managing to refresh my Partial View, this worked fine. However, now that the refreshing works, clicking the buttons after refresh doesn't work. I believe this is because the Javascript action isn't bound to the buttons once more after the refresh event is done!
How can I make sure that my Javascript actions, in the main view, are bound to the buttons which are generated in the partial view?
Please note that I tried to put the portion of the main view in the partial view, instead. This makes sure that the actions are bound once again, but completely kills the CSS after refresh, which isn't a desirable outcome either!
Since you are essentially replacing the body of the table, you will need to re-wire the events if you do it the way you are doing it. You can also hook the event up to the parent tbody:
$(document).ready(function(){
$("#tableControl").on("click","*[data-valid]", function(){
....
});
});
I haven't tested the above but something like that should work. Or, just re-wire the events on the buttons after the partial view is refreshed on the page.
I am trying to do a simple query for info from a database through an html page. I've got all the backend stuff working fine, but I'm having trouble on the client side. I currently have a form where the user submits their ID# to get some info on their case.
But with my current setup, it returns an entirely new page and I just want to read in a text string, process it and update the content on the current html page without opening up a new one and replacing the old one. How can this be done?
Here's my code so far:
function showInfo() { } // I want to make the request here instead
<form name="register" action="http://localhost:8080/testapp/authenticate" method="get">
<p><label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
<button id="checkButton" type="submit" onClick="showInfo()">Enter</button>
</p>
</form>
My guess is that you're actually submitting the form, which is posting back to the server. What you will want to do is cancel the form from submitting and submit it using AJAX (which is what I believe you want?).
To do so, your showInfo() function should do one of these three things (I can never remember which one)
return false;
cancel the event, something like e.preventDefault()
stop the propagation, something like e.stopPropagation()
Once you've successfully prevented the form from hard-submitting, you can then do what you'd like by submitting your data via AJAX and manipulating your response however you'd like.
1st - Jason is absolutely right that what you want for this situation is AJAX, below is an example in motion.
2nd - You should be using a Javascript library such as jQuery, which might look intimidating (as it did for me at first), but it is really easy and completely worth the small effort to get it going.
3rd - With jQuery, your application tidbits should look something like this, using the example you provided:
HTML -
<p>
<label for="badge">ID #:</label>
<input id="badge" name="ID" type="text" pattern="[0-9]{6}"
placeholder="xxxxxx">
// Please note that I removed the onClick section from the line below.
<button id="checkButton" type="button">Enter</button>
</p>
JQUERY -
// The default function you described to take information and display it.
function showInfo(data) {
// Insert your function here, probably using JSON as the Content Type
}
// This is the key AJAX function, using jQuery, that takes your info and gets a
// response from the server side, the sends it to the function above in order for it
// to be displayed on the page.
function processIdInfoCheck() {
$.ajax({
type: 'post',
url: '/http://localhost:8080/testapp/authenticate',
data: {
'id': $('#badge').val();
},
dataType: 'json',
success: displayIdInfoReturn,
error: function () {
alert("There was an error processing your request, please try again");
}
});
}
// When the page loads, the code below will trigger, and bind your button click
// with the action you want, namely triggering the AJAX function above
(function ($) {
$('#checkButton').bind('click', processIdInfoCheck);
})(jQuery);
Just remember, AJAX takes some effort to get the desired effect, but when you look at page load times, request numbers, etc... It is totally worth it. Please let me know if this was helpful and if you need any specifics.