I'm trying to load in data from the database dynamically with javascript and this helper function.
The function fetches a URLs which is routed to actions that return the parameters and a message after completion (as a Promise). The message gets displayed to the end user.
parasails register Page:
methods: {
loadData: async function(url) {
let origin = window.location.origin
url = new URL(origin + url);
try{
let res = await parasails.util.backendLoad(url)
console.log(res)
this.categories = res.categories
this.showResponse = res.showResponse
}catch(err){
console.log("Error: " + err)
}
},
destroyOne: async function(id) {
url = "/api/v1/category/" + id + "/destroy"
this.loadData(url);
}
}
parasails utility:
parasails.registerUtility('backendLoad', async function backendLoad(url) {
return new Promise((resolve)=>{
fetch(url)
.then((res)=>{
if (res.ok)return res.json();
throw new Error(res.status);})
.then((data)=>{
console.log(data);
resolve(data);
})
.catch((err)=>{
let resErr = []
switch(err.message){
case "401":
console.log("an error has occured of type 401");
resErr= {showResponse: {type: 'alert-danger', message "Unauthorized"}};
resolve(resErr);
default:
console.log("an error has occured");
resErr= {showResponse: {type: 'alert-danger', message: "Unkownerror"}};
resolve(resErr);
}
})
});
});
EJS:
<div id="indexCategory" v-cloak>
<div class="container my-2">
<div :class="'alert ' + showResponse.type" role="alert" v-if="showResponse">
{{showResponse.message}}
</div>
<h1>Categories</h1>
<hr/>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr scope="row" v-for="c in categories">
<td>
{{ c.name }}
</td>
<td>
<a class="btn btn-outline-secondary btn-sm" #click="destroyOne(c.id)">Delete</a>
</td>
</tr>
</tbody>
</table>
<a type="button" class="btn btn-primary mt-4" href="/category/new">Add</a>
<a type="button" class="btn btn-primary mt-4" href="/dashboard">Back to dashboard</a>
</div>
</div>
The function loadData is called beforeMount and returns all categories as it should.
When destroyOne calls the loadData function this doesnt happen. Neither the categories nor the message get shown. The action returns the parameters as expected (as a Promise).
There are no console outputs either when calling with destroyOne.
What changes do I need to implement, so that the response from destroyOne gets shown?
Related
I am trying to display data stored in a Firebase remote database in a Vue 3 webpage with a table however when I route to the display page I return the error. This is what my code looks like.
This is the HTML that displays the table:
<template>
<section v-if="!this.results.length">
No data to show
</section>
<section v-else>
<table class="table">
<thead>
<tr>
<th scope="col">View</th>
<th scope="col">Identification</th>
<th scope="col">Name</th>
<th scope="col">Surname</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr v-for="res in results" :key="res.id">
<!-- <td><button class="btn btn-primary">View</button></td> -->
<td>{{res.idCard}}</td>
<td>{{res.name}}</td>
<td>{{res.surname}}</td>
<td>{{res.email}}</td>
<!-- <td><button class='btn btn-primary'>Update</button></td> -->
</tr>
</tbody>
</table>
</section>
</template>
And this is the Javascript. Here it is supposed to fetch the data from the firebase and push it into the results[] array.
<script>
export default {
data(){
return{
results: []
};
},
methods:{
async getData(){
console.log("Getting data");
try{
const response = await fetch("https://fir-example-56e32-default-rtdb.europe-west1.firebasedatabase.app/contact.json",{
method: 'GET'
}) //the below will parse the data thats part of the response if it is in json format; returns a promise
const responseData = await response.json();
if(!response.ok){
console.log("Something went wrong")
}
const results = [];
for (const id in responseData){
results.push({
id:id,
idCard: responseData[id].idCard,
name: responseData[id].name,
surname: responseData[id].surname,
email: responseData[id].email,
});
this.results = results;
}
}catch(error){
console.log(error);
}
},
},
//when component is fully initialised call method
mounted(){
this.getData();
}
}
</script>
the form in question
what it should look like
I have a problem to delete data in nuxtjs:
<tr v-for="(user, index) in paginatedUsers">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td>{{user.created_at}}</td>
<td><a class="btn btn-danger btn-sm" href="#" #click="deleteUser(index)">Remove</a></td>
</tr>
deleteUser(index){
this.$axios.$delete(`/users/` + this.users.data[index].id)
.then(({data}) =>{
this.users.data.splice(index, 1);
})
.catch(errors => {
console.log(errors);
});
},
when click on any of the items, get the following error
Cannot read property '0' of undefined
OR
Cannot read property '12' of undefined
how solve this error
You should do this:
this.$axios.$delete(`/users/${this.users[index].id}`)
...
(I will left out some of the code in which I'm 100% sure in order to make the code more compact) I have a main view (the main view doesn't have any html-head-body because it is included in Layout)...
<div class="content-wrapper">
<div id="user-files-table-wrapper">
<!-- Partial view for user file management to be rendered there-->
</div>
</div>
<link rel="stylesheet" href="~/css/user-files-table-style.css"/>
#section Scripts
{
<script type="text/javascript" src="~/js/user-file-manager.js"></script>
}
..and a Partial view
<h3>User files ("Delete" and "Download" buttons can be clicked with invalid XML files only)</h3>
<table id="user-devices-table">
<tr>
<th>User file</th>
<th>Assigned email</th>
<th>Is valid</th>
<th>Delete button</th>
<th>Download button</th>
</tr>
#foreach (var userFileViewModel in Model)
{
#foreach (var file in userFileViewModel.UserFiles)
{
if (isValid == false && isXml)
{
<tr class="user-file-row invalid">
<td>#file.FileName</td>
<td>#userFileViewModel.Email</td>
<td>#file.IsValid</td>
<td>
<a class="btn btn-danger" asp-controller="Admin" asp-action="Delete" asp-route-userFileId="#file.UserFileID" asp-route-fileName="#file.FileName">Delete</a>
</td>
<td>
<input type="button" id="#file.FileName" class="btn btn-primary download-button" value="Download" />
<p class="download-result">File has been downloaded successfully</p>
</td>
</tr>
}
}
}
}
</table>
...and some JS:
$(document).ready(function () {
$(document).on("click", ".btn.btn-primary.download-button", function () {
const fileName = $(this).attr("id");
const clickedButtonRowIndex = $("input[type='button']").index(this);
downloadUserFile(fileName, clickedButtonRowIndex);
});
});
function downloadUserFile(fileName, rowIndex) {
$.ajax({
url: "/Admin/Download",
data: { fileName: fileName },
success: function (data) {
processProvidedFile(data, fileName);
showDownloadResult(rowIndex);
},
error: function (error) {
alert(`An error occured: ${error.responseText}`);
}
});
}
function processProvidedFile(data, fileName) {
fetch(data)
.then(resp => resp.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
.catch(() => alert("An error occured"));
}
function showDownloadResult(rowIndex) {
$(".download-result.active").removeClass("active");
$(".download-result").eq(rowIndex).addClass("active");
}
...and some CSS:
.download-result {
display: none;
}
.download-result.active {
display: block;
}
In general, my task is to download the file and show that the file has been successfully downloaded. Files are downloaded normally, no problem with it. My issue is that the showDownloadResult(rowIndex) function not working as expected. Chrome debugger hits it with a correct rowIndex, but neither remove an active class nor adding it. I checked the function in JSFiddle - it works as expected there, but not in my partial view. What am I doing wrong?
I want to disable button Assign when it clicked, bacause it should assign only once so i can achieve this, I have done the following code in HTML:
<table class="table details">
<thead>
<tr>
<th sort-by="firstName">User Name</th>
<th sort-by="lastName">Description</th>
<th sort-by="Budget" sort-init="desc">Bid Amount</th>
<th sort-by="lastName">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="issue in issues | filter:filter">
<td><strong><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.UserName }} </strong></td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.Description }}</td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{issue.Bid_amt}}</td>
<td>
<div ng-controller="ExampleCtrl_Assign">
<div ng-show="AsgHide">
<button type="button" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
</div>
</div>
<div ng-controller="ExampleCtrl_Delete">
<div ng-show="AsgHide" >
<button type="button" ng-click="DeleteRecord(issue.ID)">Delete</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
And JavaScript Code is as following:
var app = angular.module('siTableExampleApp_Assign', []);
app.controller('ExampleCtrl_Assign', ['$scope','$http', function ($scope, $http) {
var user2 = window.localStorage.getItem('UserId');
var Basic = window.localStorage.getItem('Basic');
var Token = window.localStorage.getItem('Token');
$scope.FunctionDisable = function (i) {
$("#rbutton'+i+'").attr("disabled", "disabled");
}
$scope.AssignRecord = function (ID, Description, Bid_amt) {
var BidID = ID;
var date = new Date();
encodedString = {
"ID": 1,
"Travel_Info_ID": travel_info_id,
"Bid_ID": parseInt(BidID),
"Description": Description,
"Bid_amt": Bid_amt,
"Status": "InProcess",
"User_ID": user2,
"Entry_Date": date,
"Update_Date": date
}
$http({
method: 'POST',
url: 'http://saisoftwaresolutions.com/v1/Assigned_Bids/Assigned_Bid/Create',
data: encodedString,
headers: {
'Authorization': 'Basic ' + Basic,
'Token': Token
}
})
.success(function (data, status, headers, config) {
console.log(headers());
console.log(data);
if (status === 200) {
//window.location.href = 'http://localhost:22135/BDetail/Index';
} else {
$scope.errorMsg = "Login not correct";
}
})
.error(function (data, status, headers, config) {
$scope.errorMsg = 'Unable to submit form';
})
Use can always use ng-disabled directive provided by Angular to disabled html elements.
I have made one example based on your requirements and help it will solve your issue:
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items">{{item.User_ID}}: {{item.User_Name}}
<button ng-click="handleClick($index)" ng-disabled="item.disabled">
{{item.User_Name}}
</button>
</li>
</ul>
</div>
function MyCtrl($scope) {
$scope.items = [
{
User_ID: '10',
disaled: false,
User_Name: 'ABC'
}, {
User_ID: '11',
disaled: false,
User_Name: 'XYZ'
}
];;
$scope.handleClick = function(index){
$scope.items[index].disabled = true;
}
}
Angular has a directive just for this: ng-disabled.
From their official documentation:
This directive sets the disabled attribute on the element if the
expression inside ngDisabled evaluates to truthy.
So you can set a boolean value in your code-behind to true and have that evaluate inside your button. For example:
<button type="button" ng-disabled="issue.IsDisabled" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
Also, check out the example in their documentation and this jsfiddle: https://jsfiddle.net/simpulton/q8r4e/.
I'm trying to us an ajax request to return search results. When I submit the search it returns back my json data on a plain black and white page. How do I get it to stay on the page and act out the rest of my javascript? I think the problem is either event.preventDefault isn't working right or the return statement in the controller is stopping anything further from happening.
Here are my code snippets:
HTML
<div id="contactform">
<p>Search for a Contact</p>
{{ Form::open(array('route' => 'contacts.results', 'method' => 'post', 'id' => 'contactsearchform')) }}
{{ Form::text('contactsearch', null, array('id' => 'contactsearch', 'placeholder' => 'Name')) }}
<button type="submit">Search</button>
{{ Form::close() }}
</div>
<div id="search_results">
Search Results
<table cellpadding="0" cellspacing="0" border="0">
<thead>
<tr>
<td class="name first">Name</td>
<td class="phone">Phone</td>
<td class="email">Email</td>
<td class="lot">Lot</td>
<td class="edit last"></td>
</tr>
</thead>
<tbody>
<tr>
<td class="name first"></td>
<td class="phone"></td>
<td class="email"></td>
<td class="edit last"></td>
</tr>
</tbody>
</table>
</div>
Javascript
$('contactsearchform').submit(function(event) {
event.preventDefault();
var dataString = $(this).serialize();
console.log('Submitted Data:\n' + dataString);
$.ajax({
type: "POST",
url: "/contacts.results",
data: dataString,
error: function(){
console.log("Something is wrong. Please inform Admin");
},
success: function(resultData){
console.log('Result Data:\n' + resultData);
resultDataP = $.parseJSON(resultData);
console.log('Parsed Data:\n' + resultDataP);
if(resultDataP.table){
$('#search_results').html(resultDataP.table);
$('#search_results').fadeIn();
$('#contactsearchform input').blur();
}else{
console.log("Something didn't work.");
}
}
});
return false;
});
Controller
public function showSearch()
{
return View::make('portal.search');
}
public function doSearch()
{
// Search for contacts here
$search = Input::get('contactsearch');
$contacts = DB::table('contacts')->where('last_name', 'LIKE', "$search")->get();
if (count($contacts) != 0) {
$response = [
'status' => 'success',
'msg' => 'Contacts matched your search.',
'results' => $contacts
];
}
else {
$response = [
'status' => 'error',
'msg' => 'No contacts matched your search.'
];
}
return Response::json($response);
}
And my routes
// Search for contacts
Route::get( '/portal/contacts', array(
'as' => 'contacts.search',
'uses' => 'PortalController#showSearch'
) );
Route::post( '/portal/contacts', array(
'as' => 'contacts.results',
'uses' => 'PortalController#doSearch'
) );
you should change your javascript thing a bit use it like following
/** consider the hash before the id of form you haven't added one so its not considering the form
also you need to change the url of you $.ajax call put url:'/portal/contacts' because jquery don't understand name of laravel route
**/
$('#contactsearchform').submit(function(e){
........
});