Rails Frontend Trying to save autogenerated data to database without form - ruby-on-rails

I'm new to ruby on rails. I'm trying to save data that is generated by itself to the database. i have looked into and found I was meant to use ajax, however all the videos/forums i have seen are example of ajax that use form and not refreshing page. i want to save data automatically without pressing submit.
Assume that the project is fresh project with postgresql as the database. I have created a database that can hold geo points by using postgis. i have created another page where it has map implemented where i can manully pin location. I want to save the manuuly pinned location to the database.
function onMapClick(e) {
alert("You clicked the map at " + e.latlng);
}
mymap.on('click', onMapClick);
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
The e.latlng holds the geopoint, but i dont know how to save it the database if the user clicks anywhere on the map.

You don't need submit form to use ajax.
Basically what you want is add event listener to the map, and when user click then send ajax request to the controller.
For example, let's say that your map is inside div with id my-map.
If you use jQuery you can write something like this:
$('#my-map').on('click', function() {
# add your logic here
$.ajax({
url: 'your-url',
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
'let': data you want to send to backend
})
}
Hope it works!
EDIT:
After I looked your code I found that you can not have jQuery in your project so you can not use jQuery ajax. You need use vanilla javascript. So instead this snippet above, you can write this.
var xhttp = new XMLHttpRequest();
const params = { saving_location: { geoPoints: e.latlng } }
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == 4 && xhttp.status == 200) {
alert(http.responseText);
}
}
xhttp.open("POST", "/saving_locations", true);
xhttp.setRequestHeader('Content-Type', 'application/json', 'Accept', 'application/json');
xhttp.send(JSON.stringify(params));
Also add protect_from_forgery with: :null_session in your application controller and skip_before_action :verify_authenticity_token in your Saving Location controller.(under before_action).
Here is good blog post why you need this https://blog.nvisium.com/understanding-protectfromforgery
Please notice that you wan't save your database, because your geoPoints type in database is type of point and you send string to rails controller. I never work with points in rails so I can not help you here.(You can always add two columns in db, one for longitude and one for latitude and then store numbers instead point)

Related

Setting initial value for select2 with ajax data source

I use select2 for specifying recipients for the website's inner messaging system. There are users and they can send messages to each other. They can search other users by the user name.
I use the following config:
this.$select2.select2({
multiple: true,
ajax: {
url: "/userSearch",
dataType: "json",
},
templateResult: function(data) {
var user = new SomeComplexUserModel(data);
var $div = $(<div></div>");
$div.append("<img src='"+user.image.readPaths().crop+"'>");
$div.append("<span>"+user.fullName()+"</span>");
return $div;
},
templateSelection: ..the same as templateResult..
Now I want to set initial value for this. How to do that? I have the list of ids of the users that have to be selected on page load. I make the separate request to /userSearch and receive the data. Then I'm trying to push this data to the select2 somehow.
I can't create native var opt = new Option(text,value); select.append(opt) because this case templateSelection gets only id and text from the option, it can't construct the user model based on this data only. It does not show users with avatars.
I tried to trigger select2:select event with {originalEvent:null,data:$.extend(ajaxResult,{selected:true,disabled:false,element:null},_type:"select")}, but it seems it does not work this direction. It emits events but is not subscribed for them.
I also tried to set this.$select2.val(ajaxData); this.$select2.trigger('change'), after select2 initialization, but it does not work either.

MVC Button Click performs action without redirecting

I have a table where users are allowed to "tick" or "cross" out a row. Ticking a row changes the status value to "Approved" and crossing it changes it to "Disapproved". I'm currently using the Edit scaffold to perform it. How do I do this without having the user being redirected to the view. I just want the user to click it and the page refreshes, with the status value being updated.
I'm not sure what code to post here either since I don't know how to write it. If any part of my program is required, please let me know. I'll include it here. Thank you :>
Add css classes to the 2 buttons "approve-btn" and "reject-btn".
Create javascript function to approve and reject and bind them to
the 2 classes
Create 2 backend functions
Make ajax calls from the JS functions to your backend functions passing the id of the row item
In the "success:" of the ajax call manage the change of the status to show "approved" or "rejected"
To make ajax call you can use the following example (although there are tons of example on google). Since you're modifying data you should use POST call and since it is a POST call, you should add a RequestVerificationToken to prevent CSRF attacks.
function Approve(id){
securityToken = $('[name=__RequestVerificationToken]').val();
$.ajax({
url: '/YourControllerName/Approve/' + itemId,
type: 'POST',
data: {
"__RequestVerificationToken": securityToken
},
success: function (data) {
if (data == 'success')
//use jQuery to show the approved message;
else
alert("something went wrong");
},
error: function (request, err) {
alert("something went wrong");
}
});
}
The Token should be created in the View adding this line:
#Html.AntiForgeryToken()

Confused about passing parameters from JavaScript Ajax call back to controller to render a form

Scenario: I click on some objects,table rows,etc on my page and I get their IDs for example I click on Providers list and get provider_id. And then I click on a button on the page:
Now I have a service that accepts those parameters and passes back to me a JSON which I want to show it in a Table form in my next page. So this button click is responsible for that.
So the page I am gonna show that Table in it is Pharmacy/Patients so I have a
PatientsController#index method.
Now in JS side I am doing an Ajax call like this:
// provider_id is global var and coming from the clicks on other parts of the page.
//so we have some value like 234 for it.
$('.personlistbtn').click(function(e) {
$.ajax({
type: 'GET',
data : { 'provider' : provider_id, 'therapeutic_class' : 'all' },
url: '/pharmacy/patients',
async: false,
success: function (data) {
// not sure what to write in here really.
},
error: function () {
// show some oops error
}
}
});
});
So that makes the call to /pharmacy/patients
Now I am confused how to handle it from there?
PatientsController: Maybe something like this?
def index
if request.xhr?
#my_json = MyNetHTTPFunction.getMeBackJSON(params)
end
end
MyNetHTTPFunction.getMeBackJSON(params) is just a method I have written that accepts the query params I am passing to it ( which hopefully are coming from Ajax call right? and queries the web-service and returns me back the JSON I need to use in my View.

Counting clicks to external links with rails

I have Entry model with url field, which contains link to external site.
In view I list these links, and now I'd like to start counting when someone clicks it, and keep this info in database. What's the best way of doing it?
You can easily use google analytics to track outbound links: http://support.google.com/analytics/bin/answer.py?hl=en&answer=1136920
If that is not an option you will need to add some javascript to your links make an ajax request to the server to increment the count before transferring the user to the new url. Something similar to this jquery code:
$('a').click(function(){
var stored_ulr = $(this).attr('href');
$.ajax({
url: #your server url to increment count,
data: #data you need to send,
success: function() { window.location = stored_url; },
});
return false;
});
The above code is just a general outline. You will have to fill in the blanks and make it work for your needs.

jQuery Dialog posting of form fields

I'm trying to do some data entry via a jQuery modal Dialog. I was hoping to use something like the following to gather up my data for posting.
data = $('#myDialog').serialize();
However this results in nothing. If I reference just the containing form instead myDialog then I get all the fields on the page except those within my dialog.
What's the best way to gather up form fields within a dialog for an AJAX submission?
The reason this is happening is that dialog is actually removing your elements and adding them at root level in the document body. This is done so that the dialog script can be confident in its positioning (to be sure that the data being dialog'd isn't contained, say, in a relatively positioned element). This means that your fields are in fact no longer contained in your form.
You can still get their values through accessing the individual fields by id (or anything like it), but if you want to use a handy serialize function, you're going to need to have a form within the dialog.
I've just run into exactly the same problem and since I had too many fields in my dialog to reference them individually, what I did was wrap the dialog into a temporary form, serialize it and append the result to my original form's serialized data before doing the ajax call:
function getDialogData(dialogId) {
var tempForm = document.createElement("form");
tempForm.id = "tempForm";
tempForm.innerHTML = $(dialogId).html();
document.appendChild(tempForm);
var dialogData = $("#tempForm").serialize();
document.removeChild(tempForm);
return dialogData;
}
function submitForm() {
var data = $("#MyForm").serialize();
var dialogData = getDialogData("#MyDialog");
data += "&" + dialogData;
$.ajax({
url: "MyPage.aspx",
type: "POST",
data: data,
dataType: "html",
success: function(html) {
MyCallback(html);
}
});
}
Form element inside dialog is removed from form and moved to the end of the body. You need something like this.
$("#dialog_id").dialog().parent().appendTo($("#form_id"));
jQuery("#test").dialog({
autoResize:true,
width:500,
height:600,
modal: true,
bgiframe: true,
}).parent().appendTo("form");
This works like charm

Resources