I have been working on a project that uses knockout for databinding from javascript to html. I am also reading data from a PLC using ajax, the data from the ajax request will put into the knockout viewmodel and shown on the webpage. I am having some trouble with the updating of the data binding.
I searched on the internet for help but didn't find anything so far that helped me so I hope you can help me further.
I have setup the viewmodel as following inside a javascript file:
function AppViewModel() {
var self = this;
self.hmitags = ko.observableArray(groupDataValues);
self.Capa100 = ko.observable("Cap100");
self.Testvar = ko.observable(50);
}
var viewModel = new AppViewModel();
ko.applyBindings(viewModel);
And have the data binding in the html file:
<span data-bind="text: Testvar></span>
when I now load the html file I see the value 50 as defiened in the viewmodel, so that is working. But now I want to read a variable from my PLC using ajax that is done through a function inside that same javascript file. This is how the function looks:
function ReadVariable()// function for reading out individual variables
{
// list can contain only one variable
var HMIReadList = "&paths=MainInstance.Testvar"
data.length = 0; // get rid of the data from the last query
// issue the data request
$.ajaxSetup({
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + BearerToken);
}
});
$.ajax({
type: "GET",
url: baseurl + "_pxc_api/api/variables?pathPrefix=Arp.Plc.Eclr/" + HMIReadList,
})
.done(function (data, status, jqXHR) {
viewModel.Testvar = data.variables[0].value;
console.log(viewModel.Testvar);
})
.fail(function (jqXHR, status, errorThrown) {
console.log("CreateSession Error: " + errorThrown);
console.log("Status: " + status);
console.dir(jqXHR);
alert("CreateSession $.ajax failed. Status: " + status);
});;
}
I am using a button in the html page to call this function. In the console I can see that it is reading a value from the PLC and that it is different that the initial value 50. But on the html page it is not changing. I am not sure why it isn't working I have been looking around for some solutions but have not found anything that is working.
A knockout observable is a function. In order to update the value of the observable, you need to invoke the function with the new value as follows:
viewModel.Testvar(data.variables[0].value)
Related
I am trying to use jquery ajax to make a post request that returns some response but it does not seem to work properly. Sometimes it works after a long wait, other times it does not work at all.This is my code.
<script type="text/javascript">
const id = $('#auth').val();
$("#set").click(function(){
$('.spinner-grow').show();
$.post("https://ravesandboxapi.flutterwave.com/v2/gpx/transactions/escrow/settle",
{
id: id,
secret_key: "FLWSECK-25*******************0628-X"
},
function(data, status){
alert("Data: " + data + "\nStatus: " + status);
$('.spinner-grow').hide();
});
});
</script>
what might be the issue here?
The following is a complete example of a AJAX post is handled via jQuery. Just sharing it for reference.
var url = "api/path/to/your/controller";
var data = {};
data.id = id;
data.secret = 'your-secret';
$.ajax({
type: 'POST',
url: url,
data: data,
success: function (resultObject) {
console.log(resultObject);
},
error: function (err) {
console.log('An error occured');
}
});
If you are getting a 404 error, better check the path to the API. You can use a tool like Postman to validate your requests and then try implementing the same in code.
Also make sure that there is no CORS issue as from your code we cannot understand if your post is triggered from the same domain.
I am completely stuck since two hours and definitely need your help. Disclaimer: I am not a coder - just a guy who is trying to mock up an idea.
So my page is actually working fine but I thought about moving content from a modal-popup to an actual sub-page. Meaning: If a user clicks on a button, some data points from the current page are being collected and passed to another view which shall be rendered using the data points as input.
EDIT: For clarification: The button is on /results.php where data is generated dynamically. The method should take some data points from here and generate a new view and render it at /buy.php or maybe at /buy/custom.php
My thoughts:
Normal redirect without parameters: Internal Link
Updating page-content without redirect but with parameters: Ajax
So combining my thoughts -> use ajax and return a new fresh view.
What I tried:
$("body").on("click", ".fa-shopping-cart", function() {
var $para1 = $(this).attr("data1");
var $para2 = $(this).attr("data2");
var $para3 = $(this).attr("data3");
var $para4 = $(this).attr("data4");
$.ajax({
url: "buy",
data: {
a: $para1,
b: $para2,
c: $para3,
d: $para4
},
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
type: "post",
success: function(response){
console.log(response);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});});
Routing:
Route::post('/buy', 'PageRouting#buy');
Controller:
public function buy()
{
$para1= $_POST['a'];
$para2 = $_POST['b'];
$para3 = $_POST['c'];
$para4 = $_POST['d'];
// some magic to output $data
return view('pages.buy', compact("data"));
}
buy.blade.php exists and displays $data with help of an foreach-loop.
So, when I first clicked the button the obvious happend:
The view ('pages.buy') is logged / displayed in my console in plain html and not rendered in the browser.
Now I am sitting here since two hours and I have no clue whatsoever. I read some blog post saying that you cannot redirect within an ajax-call. Unfortunately the post did not gave any hint on how to do it instead.
Can someone help me?
All best
If you want to replace entire document with the response you have to use document.write but it's not the best thing to do. Why don't you use normal form submit if you need to return a view?
success: function(response){
document.write(response);
},
P.S. if you want also to change the url, use the history manipulation functions.
https://developer.mozilla.org/en-US/docs/Web/API/History_API
in your buy method -
public function buy ()
{
....//some stuff to get $data
$html = view('pages.buy', compact("data"))->render();
return response()->json([
'success' => true,
'html' => $html
])
}
in your ajax success function
success: function(response){
if(response.success)
{
$('#elementId').html(reponse.html) // or whatever you need
}
},
In trying to cleanup my code base, I moved all of my javascript from script tags to their own javascript file. After doing that, all of my ajax calls are failing.
Here's the javascript, this is EXACTLY how it was in the *.cshtml file, excluding the script tags:
$(function () {
$("#weightList").change(function () {
var weight = $("#weightList").val();
var conference = $("#conference").val();
$("#wrestlerAList").prop('disabled', true);
$("#wrestlerBList").prop('disabled', true);
$.ajax({
url: '#Url.Action("GetByWeight", "Wrestler")',
data: {
weight: weight
},
type: 'POST',
success: function (data) {
var wrestlers = "<option></option>";
$.each(data, function (i, wrestler) {
wrestlers += "<option value='" + wrestler.Value + "'>" + wrestler.Text + "</option>";
});
$("#wrestlerAList").html(wrestlers);
$("#wrestlerBList").html(wrestlers);
$("#wrestlerAList").prop('disabled', false);
$("#wrestlerBList").prop('disabled', false);
},
error: function (error) {
alert("An error occurred retrieving the wrestlers for this weight.");
}
});
});
});
I've tried removing the "$(function () {...});" but that didn't work. Is there other syntax required when the javascript is not directly on the cshtml page?
Edit: I'm loading my javascript file at the very end of the cshtml file, right before the closing tag.
Also, I'm getting a 404 back. If the code stayed the same, why would it now be getting a 404?
url: '#Url.Action("GetByWeight", "Wrestler")',
that line needs to be rendered on a cshtml page. it doesnt get processed in a .js file.
The problem is with the way you are setting the ajax url
url: '#Url.Action("GetByWeight", "Wrestler")'
The ASP.NET MVC tag helper #Url.Action() will not work inside a .js file.
You could place the url in a hidden form field and read it from there.
Place this somewhere in the .cshtml preferably outside of any forms so it is not posted back in the form for any reason.
#Html.Hidden("ServiceUrl", Url.Action("GetByWeight", "Wrestler"))
Then use the code below to set the jQuery ajax url
url: $('#ServiceUrl').val(),
I'm a bit new to Javascript and I want to do something I feel like should be pretty simple. I have a web completion service built and I just need to get those completions into the page. I basically want something like this:
<script>
function(search_string){
http.request('www.fake.com/search_complete/' + search_string, function(response) {
response = JSON.parse(response);
//do something with parsed data
});
}
</script>
<input type="search" placeholder="Search..." />
Are you just trying to make a request and use the data returned? If so, just make an ajax request and update the html with the data you get back
var request = new XMLHttpRequest();
request.open('POST','http://www.fake.com/whatever.php?val1='+search_string,true);
request.send();
request.onreadystatechange = function(){
if(request.readyState == 4 && request.status=200){
//The request has been completed, handle the data
var data = JSON.parse(request.responseText);
}
}
This must help. Example integration of jQuery UI autocomplete from remote web service.
http://salman-w.blogspot.in/2013/12/jquery-ui-autocomplete-examples.html
Use jquery:
$.ajax({type: "GET", dataType: 'json', contentType: "application/json", url: "yoururl", success: function (data) {
//data is a javascript object that contains the data returned by your webservice json
}, error: function(xhr, status, error) {
// Display a generic error for now.
alert("Error: " + xhr + " " + status + " " + error);
}});
This code will make a call to a webservice using ajax and javascript. It will return the data from the webservice in the data object.
I don't know why this is happening since there are other functions in this page that use also getJSON and they do work. I have the following JavaScript Code
function openSOPNotesDialog() {
var url = '<%: Url.Action("GetSOPNote", "SalesOrder") %>';
var id = <%: Model.SodID %>;
$.getJSON(url, { sodId : id }, function(data) {
alert("data: " + data);
$("#hidSOPSODId").val(data.SodID);
$("#hidNoteId").val(data.NoteID);
$("#txtSOPNotes").val(data.Description);
$("#sopNotesDialog").dialog("open");
});
}
and then I have this method on the SalesOrderController class
public JsonResult GetSOPNote(int sodId)
{
var service = new SodSrv();
var note = service.GetSOPNotes(sodId);
return Json(note, JsonRequestBehavior.AllowGet);
}
However, the method is never called in the debugger and data is returned as null (which is what I'd expect). As I said before there are other calls in this page and they are also doing GET requests so I don't know what may be the cause.
Sounds like the browser is pulling the data from the cache since it is a get request. Make sure to set no cache headers on the server if it is not meant to be cached.
Try adding an error handler to try to track down what the issue is:
$.ajax({
dataType: 'json',
url: url,
data: { sodId : id },
success: function(data) {
alert("data: " + data);
$("#hidSOPSODId").val(data.SodID);
$("#hidNoteId").val(data.NoteID);
$("#txtSOPNotes").val(data.Description);
$("#sopNotesDialog").dialog("open");
},
error: function(jqXHR, textStatus, errorThrown) {
alert("oops: " + textStatus + ": " + jqXHR.responseText);
}
});
I suspect that the reason is that getJSON uses get method and controllers normally allowed to accept only post methods. It's ease to check using any browser firebug for example.