I need to build a very simple button on a website that toggles a boolean on the server. When the boolean is True, I want to show a green icon, when it's False, I want to make it red. When a user clicks the icon, it should send a command to the server and update, then the icon should only change colors (image src) when the server has replied that the boolean has in fact been toggled.
I'm not very experienced with web apps, but I'm wondering what framework would work best for this? Is there an easy-to-use HTML5 way to do this? AJAX? Websocket? I'm using websockets on another page of the app and it's working, but it might be overkill for something this simple?
Websockets are complete overkill for this, however you said you have another part of the application done...what is your backend? If you like C#, ASP.NET has a lot of choices for you (MVC4 is my personal favorite).
In MVC you would create an action inside your pages controller to interpret some JSON passed from an AJAX call kind of like this:
public JsonResult FooData(int _id)
{
var dataContext = true;
if(_id == 7)
dataContext = false;
return Json(dataContext, JsonRequestBehavior.AllowGet);
}
...and on your client side you would call the FooData method like this:
$.ajax({
url: "MyController/FooData",
data: { _id: obj.id },
dataType: 'json',
async: true,
success: ChangeImage
});
Where ChangeImage is a javascript function set as your ajax calls' success callback function, so it might look like this:
function ChangeImage(data) {
if(data == true)
document.getElementById('myImg').src = "red.jpg";
else
document.getElementById('myImg').src = "green.jpg";
}
It's short, sweet and to the point. There's a learning curve but it's well worth the time and effort. I can't live without this framework anymore!
EDIT: Forgot to add data to pass in the ajax call, fixed now!
EDIT EDIT: I didn't add the logic of if click check bool -> if true, set false -> send flag -> if flag == 'change' change color -> if click ... etc etc etc because that's just busy work. This is more than enough to get you there though.
You don't want to send loads of data, or want pushing from the server, so I would recommend AJAX.
jQueries ajax is fine, but you might want to look at google if you want something more fancy.
Websockets are only usefull when you want much data, and really live.
Now you only want to send data from the client once and then, instead of keeping both sides up-to-date all the time.
Related
In my project I have rows of modules loaded from Partial views.
So imagine a grid of small squares with information.
There is a popup dialog for all of them, that displays the data of the clicked module.
Currently when I submit a change in the dialog, the javascript reloads the entire page. BUT, this takes a long time, and I need to be able to refresh only the one dialog.
I can imagine to make a separate js function for each type of module, and then pass some data in, so jquery can find the specific module, and then make an ajax get, for the data. But this requires me to do all the data insertion from js always. instead of using razor and MVC's built in awesomeness.
Does anyone know of a way, to call a partial view inside a div?
Also in the future I will need to reload "some" but not all the modules in an interval refresh. So for future proofing purposes:
What im looking for is something like:
function reloadElement(row, column, id){
var target = $("#div1");
// todo find row and column
target.html.partial("url", model); //<----- looking for something like this. cross fingers.
}
Thanks to GregH for a few key words, that lead to some ideas.
I solved it myself, so if you land on this problem also, here is how i solved it:
Controller:
You want to make your controller return PartialView("somePartialViewUrl", new SomeModel()), apparently saving the model and relying on the data collection isn't good enough, i hadto make a new instance of the model.
Javascript
in the "click" that handles the event, put:
$.ajax({
url: "controllerName/actionName",
data: JSON.stringify({ row:1,column:2 .... }),
contentType: "application/json",
dataType: "html",
type: "POST",
success: function (partial) {
$("#div2").html(partial);
}
});
this will override the html in your "#div2".
im sure you can also use $("#div2").innerHTML = partial; or $("#div2").load("url",parameters); and probably many other ways.
done.
I'm helping with an open source project. It's a small Go webserver running on a device containing a Raspberry Pi. I want to be able to have a user click a button on an html screen, which calls a routine in Go, which returns 2 values, a boolean and a string.
What we are wanting to do is see which network interfaces are up on the raspberry pi e.g. is the lan connection up?
To do this I really need to ping a site from each interface. This takes a few seconds for each of 3 interfaces: Lan, WiFi, and 3G.
I can do this when the page is requested and fill in an html template as the page loads, but it means waiting maybe 10 to 15 secs for the page to load, so it seems like something is broken.
So I want to be able to list each of the 3 interfaces on the page and have the user click 'test' which then calls a routine in the underlying Go webserver.
I then need to be able to display the results from the call in a couple of text areas for each interface.
What I have tried:
I have tried registering a Go function (in this case IsLANConnectionUp) using funcmap from the net/html package and calling it from the html template from a JavaScript function, like this:
<button onclick = "getLANStatus()" class="btn btn-primary">Test</button>
<script>
function getLANStatus() {
var status = document.getElementById('status');
{{ if IsLANConnectionUp }}
status.innerHTML = "Lan is up!"
{{ else }}
status.innerHTML = "Lan is down!"
{{ end }}
}
</script>
But having the template code inside the javascript code doesn't seem to work. Also, I'd like the text output from the ping command (which my Go function getLANStatus and I don't know how to extract that data from the function call. The documentation says only one value can be returned.
Searching on StackOverflow I see this: calling Golang functions from within javascript code
$.ajax({
url: "http://www.example.com/signup",
data: {username: "whatever"} //If the request needs any data
}).done(function (data) {
// Do whatever with returned data
});
But it says things like "// Do whatever with the returned data" I'm new to web programming and so don't know how to use that code. If this is the way to go, could someone please expand on this a little?
Any help would be much appreciated.
So couple different concepts here.
Render: On the initial request to your html that generates the Test button. Your go server will render that html 1 time and return it to your browser. It does not re-request dynamically unless you wire some stuff up to make the web page change.
Client: So when someone clicks your button, the function getLANStatus will be ran. You will want that function to do a few things
Through ajax, communicate with your go server through an api that will return the status of your connections as a json object. Something like
{
"3g": "up",
"lan": "down",
"wifi": "up"
}
Second, in the done part of your ajax, you will manipulate something in the DOM in order to convey that the status of the interfaces is what it is. You could do that by finding the element, then changing the text to what is returned by the object.
As a simple first step, you can alert the payload in the function that would look like this
$.ajax({
url: "http://YOUR_GO_SERVER_IP_OR_DNS:PORT/interfaces_status.json"
}).done(function (data) {
alert(data);
console.log(data);
debugger;
});
Then if you request that with the console open in chrome, you will be able to directly play with the returned data so that you know what all it reponds to.
I have a function called 'delete' like this :
<div onclick="delete($post_id, $_SESSION['id']">somelink</div>
function delete(post_id, session_id) {
var p_id = post_id;
var s_id = session_d;
$.ajax({
url:"delete.php",
type:"POST",
data: {
p_id: p_id,
s_id: s_id
},
});
})
delete.php is a page to delete the post = p_id which was added from user id = s_id.
My problem is any user can delete any post for only the console when typing in it the function 'delete();' with parameters it called and delete posts!
Any ideas, please.
You can not. Nor should you.
You should always assume that data from the client side is corrupted and should be treated accordingly. That includes form data, or in this case, a AJAX request.
This means that you have to apply validation at the server side, let PHP do it for you. E.g.: Limit the number of posts you can delete per X time. And double check that the post actually belongs to the person who is deleting it.
The reason you can't do this, is because you create javascript which is clientside. If you create a function to prevent changing the code, the client can alter the code on their machine to ignore that. You could make a function to check of the function to check is changed, but again; client can change it.
Unfortunately you can't. What you need to make sure though is making the function safe on the server which, in simple terms, boils down to
Validating every request and input parameters on the server so that people won't be able to manipulate or change server side data from client side.
make sure all data that you send to the client is originated from server as well.
one of the ways to prevent calling a function from client side is NOT to expose your methods in the global scope. and remember if your code is very critical and important, always move it to server-side. it is not a good practice to cover application design issues with programming workarounds. calling functions from client side shouldn't be an issue if the program is designed right.
First of all, this is bad. You should have authentication.
However, you can do that:
(function() {
$('#BUTTON_ID').on('click', function(post_id, session_id) {
var p_id = post_id;
var s_id = session_d;
$.ajax({
url:"delete.php",
type:"POST",
data: {
p_id: p_id,
s_id: s_id
},
});
})
})();
And add "BUTTON_ID" as id for your button.
Not that even that way, it is still not secure.
With this way, you can't call delete from the console. But someone can look into the source code and copy your ajax call and paste it into his console and it will works. It is not a good way to prevent people deleting your posts.
You should read about web application security. You should have an authentication process with tokens that expires after x time. Tokens will authenticate the user and from here, you can check if the user have the right to delete post. If the user do not have the right, you don't show the button. Then if the user call it from it console, he will get an error from the backend server.
Say I have this code here (somewhat pseudocode)
$.ajax({
url: "/api/user",
success: function(resp) {
var data = JSON(resp)
if (data.user.is_admin)
// do admin thing
else
// do something else
}
});
Basically the endpoint returns some info about the user and the callback handles the rest. Can I put a breakpoint before the if statement and change data.user.is_admin to be true before the statement is ran? Is that possible?
It is absolutely possible. You can't trust on client code for any security check. Anyone could play with it using something as simple as browser developer tools.
That kind of logic must be on server side, I'm afraid that you have no choice if you need yo keep that safe.
On one of my pages I have "tracking.php" that makes a request to another server, and if tracking is sucessful in Firebug Net panel I see the response trackingFinished();
Is there an easy way (built-in function) to accomplish something like this:
If ("tracking.php" responded "trackingFinished();") { *redirect*... }
Javascript? PHP? Anything?
The thing is, this "tracking.php" also creates browser and flash cookies (and then responds with trackingfinished(); when they're created). I had a JS that did something like this:
If ("MyCookie" is created) { *redirect*... }
It worked, but if you had MyCookie in your browser from before, it just redirected before "track.php" had the time to create new cookies, so old cookies didn't get overwritten (which I'm trying to accomplish) before the redirection...
The solution I have in mind is to redirect after trackingFinished(); was responded...
I think the better form in javascript to make request from one page to another, without leaving the first is with the ajax method, and this one jQuery make it so easy, you only have to use the ajax function, and pass a little parameters:
$.post(url, {parameter1: parameter1value, param2: param2value})
And you can concatenate some actions:
$.post().done(function(){}).fail(function(){})
And isntead of the ajax, you can use the $.post that is more easy, and use the done and fail method to evaluate the succes of the information recived
As mentioned above, AJAX is the best way to communicate between pages like this. Here's an example of an AJAX request to your track.php page. It uses the success function to see if track.php returned 'trackingFinished();'. If it did then it redirects the page 'redirect.php':
$.ajax({
url: "track.php",
dataType: "text",
success: function(data){
if(data === 'trackingFinished();'){
document.location = 'redirect.php';
}
}
});
The example uses JQuery.