MVC 4 Ajax call is not made - javascript

I've been trying to fix a problem in my app for a couple of days now and I can't figure out what's happening.
I'm developing a MVC 4 application. I have a view in which there's a div that I load with more html with an ajax call that is executed on the $(function() { ... });. That ajax call works fine.
Problems start when I make the second ajax call. I paste the code below :-
In the main view :-
<div class="body" id="loadedData">
</div>
<script type="text/javascript" charset="utf-8">
$(function(){
loadData("#Url.Action("Authorizations","User", new { id = Model.ID })");
});
function loadData(url){
$.ajax({
type: 'GET',
url: url,
success: function (data) {
$("#loadedData").html(data);
}
});
}
</script>
And the partial view that is loaded in the div it's this:
#if (ViewBag.UserAuths != null){
<table>
<tr>
<th>
Operations
</th>
<th></th>
</tr>
#foreach (var prod in ViewBag.UserAuths){
<tr>
<td>
#prod[0]
</td>
<td>
Remove
</td>
</tr>
}
</table>
}
The problem happens when I click on the link in the HTML that's loaded by ajax (Remove). When i click, the page 'blinks' but nothing happens. I've put a breakpoint in the RevokeAccess function in UserController and it never stops.
Please help!
Edit:
There's other thing, when i click on the link, in the Chrome console it's shown a "Uncaught SyntaxError: Unexpected token )" message, but it disappears very quickly, i don't know why.

As you are using jQuery don't use inline events. Bind click event using jQuery. As you are fetching Partial View you can use .load() which is much simpler.
Script
<script type="text/javascript">
$(function(){
$("#loadedData").load("#Url.Action("Authorizations","User", new { id = Model.ID })");
$("#loadedData").on('click', '.anchor', function(event){
event.preventDefault();//Stop default action
$("#loadedData").load(
$(this).data('url'), //Url
{ id: $(this).data('id'), op : $(this).data('op')}, //Parameters
function(){
//Perform any action if any
}
);
})
});
</script>
Change Your Partials as
#if (ViewBag.UserAuths != null){
<table>
<tr>
<th>
Operations
</th>
<th></th>
</tr>
#foreach (var prod in ViewBag.UserAuths){
<tr>
<td>
#prod[0]
</td>
<td>
<a class='anchor' href="#" data-url='#Url.Action("RevokeAccess", "User")' data-id="#ViewBag.UserID" data-op="#Int32.Parse(prod[1])">Remove</a>
</td>
</tr>
}
</table>
}

Related

How can I pass an ID from selected table row to my AJAX function that fetching data

Sorry to bother, I'm having a trouble passing and ID to my AJAX function.
I wanted to pass the ID of the selected table row to my AJAX function and use it for my query in my controller
this is the code for my table row
<div class="container">
<h2 style="margin-top: 12px;" class="alert alert-success">Details</h2><br>
<div class="row">
<div class="col-12">
<table class="table table-bordered" id="">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<td colspan="2">Action</td>
</tr>
</thead>
<tbody id="users-crud">
#foreach($merchants as $merchant)
<tr id="user_id_{{ $merchant->id }}">
<td>{{ $merchant->id}}</td>
<td>{{ $merchant->first_name }}</td>
<td>{{ $merchant->email }}</td>
<td><a id="getData" onClick="getData({{$merchant->id}})" class="btn btn-info">Show</a>
</td>
</tr>
#endforeach
</tbody>
</table>
{{ $merchants->links() }}
</div>
</div>
</div>
upon click show ID should pass it to my AJAX function,
this is the code of the script
<script type=text/javascript>
$(document).ready(function() {
});
function getData(id){
$('#myModal').modal('show');
$.ajax({ //create an ajax request to display.php
type: "GET",
url: "getproducts/",
// dataType: 'json',
data: {id: id}, // This will be {id: "1234"}
success: function (data) {
$("#id").html(data.id);
$("#first_name").text(data.first_name);
}
});
};
</script>
And ID will be use for my query in my controller, this is my controller's code, note that the number 1 in my where query is hard coded, I wanted to put the ID that I get from the selected table
public function getproducts()
{
$merchants = DB::table('merchants')
->select('merchants.*', 'product.product_name as product_names')
->join('product','product.id','=','merchants.id')
// THE NUMBER 1 IS HARD CODED
->where('merchants.id', 1)
->paginate(8);
return response()->json($test, 200);
}
Every method in a Laravel Controller can have arguments "injected" into them, including the Request $request variable. Add this to the top of your Controller after your namespace declaration:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Then modify your method:
public function getproducts(Request $request) {
...
}
Then, instead of hard-coding the value 1, you pull it from your $request object:
->where('merchants.id', $request->input('id'))
The full documentation can be seen here:
https://laravel.com/docs/9.x/requests#accessing-the-request
Your code seems fine to me. What is the issue you are facing? But you can improve code by bit more.
<td><a id="getData" onClick="getData({{$merchant->id}})" class="btn btn-info">Show</a>
Instead you can use a global class. Also using same HTML id in a class is not good practice.
<td><a class="merchant_info" data-id="{{$merchant->id}}" class="btn btn-info">Show</a>
Now need modification to jQuery code
<script type=text/javascript>
$(document).ready(function() {
$('.merchant_info').click(function(e){
e.preventDefault();
var dataId = $(this).attr("data-id");
// Now do the Ajax Call etc
});
});
</script>

Bootbox.confirm() dialog box is not showing up

I am trying to use bootbox.confirm() for a simple confirmation box but dialog box is not showing up on the page. There are no problems in the chrome's console (in fact there is nothing in there). However when I click my button , for which the dialog box is supposed to appear, the additional div of the box can be seen in the elements section of the chrome's developer tools but nothing can be seen on the page.
here is the javascript.
$(document).ready(function () {
$("#customers .js-delete").on("click", function () {
var button = $(this);
bootbox.confirm("Are you sure you want to delete this Customer?", function (result) {
if (result==true) {
$.ajax({
url: "/api/customers/" + button.attr("data-customer-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove();
}
});
}
});
});
});
here is html of the page
<table id="customers" class="table table-bordered table-hover">
<thead>
<tr>
<th>Customer</th>
<th>Membership Type</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
#foreach (var customer in Model)
{
<tr>
<td>#Html.ActionLink(customer.Name, "Edit", "Customers", new { id = customer.Id }, null)</td>
<td>#customer.MembershipType.Name</td>
<td>
<button data-customer-id="#customer.Id" class="btn btn-link js-delete">Delete</button>
</td>
</tr>
}
</tbody>
</table>
I copied your code to my environment and its works fine. Just make sure you did initialize the bootbox.js in the bundleConfig file under the bootstrap library other way the bootbox will not render in your page
"~/scripts/bootbox.js"

Use link found in the a tag to make an AJAX request on click

I have a table with dynamic values example below. I want to use the url in my dynamic url in my a tag with AJAX request base on what ID the user clicks on. When user clicks on ID 1 in the table below I want to pass the url in that a tag to my script in the AJAX url section. I would be thankful for any help
<table >
<thead>
<th data-field="status">ID</th>
<th data-field="actions">action</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td><a id="test" href="test.php?id=1" >1</a></td>
</tr>
<tr>
<td>2</td>
<td><a id="test" href="test.php?id=2" >2</a></td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(){
$("#test").click(function(){
$.ajax({url: "", success: function(result){
$("#div1").html(result);
}});
});
});
</script>
NOTE: You shouldn't use the same id for multiple elements on the same page. I changed your ID to use class instead
I also added a preventDefault() to prevent the link from doing its normal job (unless you want to in which case remove that line)
$(document).ready(function(){
$(".test").click(function(e){
theURL = $(this).attr('href');
console.log(theURL); // can be removed just included for testing
e.preventDefault();
$.ajax({url: theURL, success: function(result){
$("#div1").html(result);
}});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table >
<thead>
<th data-field="status">ID</th>
<th data-field="actions">action</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td><a class="test" href="test.php?id=1" >1</a></td>
</tr>
<tr>
<td>2</td>
<td><a class="test" href="test.php?id=2" >2</a></td>
</tr>
</tbody>
</table>
change ID to class - IDs need to be unique <a class="test" href="test.php?id=1">...
prevent the link from being followed
use load - it is simpler
Like this
$(function(){
$(".test").click(function(e){
e.preventDefault();
$("#div1").load(this.href); // or if you insist: $.ajax({url: this.href,...
});
});
PS: If the links are inserted by script, you need to delegate - here I assume the table had an ID and exists at page load
$("#tableId").on("click",".test",function(e){

Can I call a jquery or javascript function in grails g:each element?

I want to call a jquery function in grails g:each element, i'm using a function call on page load to filter a table which has a loop as follows
<g:each in="${sampleTypes}" status="i" var="sampleType">
<div class="uniq">${sampleType}</div>
<table id="sampleTable">
<thead>
<tr>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="CustomerId" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="OrderNo" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="DateCreated" /></th>
<th class="no-sort"><g:message code="labWorkItem.testUnit.label"
default="Test unit" /></th>
<th class="no-sort no-visible"><g:message
code="labWorkItem.sampleType.label" default="Sample Type" /></th>
</tr>
</thead>
<tbody>
<g:each in="${labWorkItemInstance}" status="a" var="labWorkItem">
<tr class="${(a % 2) == 0 ? 'even' : 'odd'}">
<td>
${labWorkItem?.order?.customer?.customerId}
</td>
<td>
${labWorkItem?.order?.orderNo}
</td>
<td>
${labWorkItem?.order?.dateCreated}
</td>
<td >
${labWorkItem?.testUnit}
</td>
<td id = "labSample">
${labWorkItem?.testUnit?.sampleType}
</td>
</tr>
</g:each>
</tbody>
</table>
<g:textField name="singleValue" value="Blood" id="someHiddenField"/>
</g:each>
i am using the class "uniq" to filter the table
function typeSampleCollected() {
jQuery.fn.dataTableExt.afnFiltering.push(function(oSettings, aData,
iDataIndex) {
if (oSettings.nTable.id != "sampleTable") {
return true;
}
var uniq = jQuery("div.uniq").html();
alert(uniq);
jQuery("#someHiddenField").val(uniq);
var someHiddenField = jQuery("#someHiddenField").val()
if(someHiddenField){
//var sampleValue = jQuery("#someHiddenField").val();
//alert(sampleValue.toString());
if (someHiddenField != aData[4]){
console.log("sampleType"+someHiddenField);
console.log("aData"+aData[4]);
return false;
}
}
else{
console.log("else condition");
}
return true;
});
}
The problem is, it executes at the first on page load, only the first data of the loop executed others remains the same, i want the remaining data also to execute.
jQuery + HTML answer.
Your generated HTML will be wrong because the id "someHiddenField" will be duplicated. An id has to be unique within the HTML document. View the source of the document to check. Copy into an IDE or use w3c validator to check.
Once you have unique ID's you need to iterate over them and run your filter.
I am not sure whether by filter you are sending information back to the server. i.e. text blood results in only content relating to blood being displayed. I don't see any events in your code. Is the code incomplete?
A similar thing - click on an icon to only display items relating to that class. View code:
<g:each in="${assetTypes}" status="i" var="assetType">
<li>
<span class="atext">${assetType.name?.encodeAsHTML()}</span>
</li>
</g:each>
I used delegate() to late-bind jQuery to the click - use go() after 1.7 jQuery. The javascript had to be in a grails view because I use the gsp tags. With delegate() it could be anywhere:
/* Change asset types */
jQuery('body').delegate('[name=assetTypeSelector]', 'click', function() {
var newAssetIconId = jQuery(this).attr("id").split("-").pop();
// set the asset type.
${remoteFunction(controller: 'assetType', action: 'selector', name: 'assetTypeSelector', update: 'assetTypeSelector', params:'\'currentAssetTypeIconId=\' + newAssetIconId')}
});
Alternatively we have had a lot of success with DataTables which is a more complete solution.

Get parameter of template in Play Framework

I have a template with parameter like this :
#(people: List[models.Person])
<html>
<head>
</head>
<body>
<table class="centered" id="table_people">
<thead>
<tr class="table_header">
<th></th>
<th class="people_column">Name</th>
<th class="people_column">Active</th>
</tr>
</thead>
<tbody>
#for(p <- people) {
<tr>
<td><button id="timesheet_view_" >View</button</td>
<td><b>#p.getName()</b></td>
<td>#p.isActive()</td>
</tr>
}
</tbody>
</table>
That code shows a list of people. And now, i wanna when click on button view, it shows information of people. To do that, i have to write something like that:
<script>
$( "#timesheet_view_<%= people[i].id %>" )
.button()
.click(function() {
people = '<%= people[i].name %>';
showTimeSheet('current', '<%= people[i].name %>');
})
</script>
But i can't find how to get value people parameter of template in Javascript. I try to use # character, but it doesn't work.
First, you have to fix your HTML code:
<td><button id="timesheet_view_" >View</button</td>:
close the button element correctly: </button with a '>'.
Second, you have to give every button a unique ID:
Your code:
#for(p <- people) {
<tr>
<td><button id="timesheet_view_" >View</button</td>
<td><b>#p.getName()</b></td>
<td>#p.isActive()</td>
</tr>
}
Try it with:
#for(p <- people) {
<tr>
<td><button id="timesheet_view_#p.id">View</button></td>
<td><b>#p.getName()</b></td>
<td>#p.isActive()</td>
</tr>
}
<script>
$(document).ready(function() {
// There are better ways to do this, but it's just for your example
#for(p <- people) {
$("#timesheet_view_#p.id").click(function(e) {
... // your javascript code here
});
}
});
</script>
In my opinion it's better to use a link here (instead of a button), because for every button you need to code extra javascript for the onclick event. Try it with a link and Play! will do the work for you:
#for(p <- people) {
<tr>
<td><a class="btn" href="#routes.Application.view(p.id)">View</a></td>
<td><b>#p.getName()</b></td>
<td>#p.isActive()</td>
</tr>
}
Btw, if you use Twitter Bootstrap you can use class="btn" and your link looks like a button.
Start your Play! application and have a look in the HTML source code. You will see your code <button id="timesheet_view_#p.id">View</button> will looks like this:
<button id="timesheet_view_1">View</button>
<button id="timesheet_view_2">View</button>
...
<button id="timesheet_view_9">View</button>
Hope this helps.
Best regards,
gfjr
You can't do it that way. Javascript is running client-side whereas Play is running server-side.
At the time your Javascript is running, the page has already been rendered and Play has done it's part.
What you can do is to capture relevant data from people and put it in data attributes.
<tbody>
#for(p <- people) {
<tr data-people-id="#p.getId()" data-people-name="#p.getName()">
<td><button class="timesheet_view" >View</button</td>
<td><b>#p.getName()</b></td>
<td>#p.isActive()</td>
</tr>
}
</tbody>
And in your script you can get the data attributes.
<script>
$( ".timesheet_view" )
.button()
.click(function() {
var row = $(this).closest("tr");
var peopleId = row.data("peopleId");
var peopleName = row.data("peopleName");
// Do whatever you want with this data...
// Not sure how the showTimeSheet is working so leave it up to you
//showTimeSheet('current', '<%= people[i].name %>');
});
</script>

Categories

Resources