I am trying to change the row of the table according to the button clicked. The row changes for the first time button is clicked, but after that row value doesn't change. Also, the event listner is removed after button changes.
HTML:
<% if(post.status === 1){ %>
<input type="button" class="btn btn-danger" value="Disapprove" id="disapproveBtn-<%= i %>">
<input type="button" class="btn btn-primary" value="Send to Moderation" id="moderateBtn-<%= i %>">
<% } %>
jQuery:
$("[id|='disapproveBtn']").click(function (e) {
console.log("CLICKED");
var trIndex = $(this).closest('tr').index();
var tr = $(this).closest('tr');
var postId = $(this).closest('tr').find("#postId").text().trim();
$.post('/admin/disapprove/' + postId, (data) => {
console.log(tr);
console.log(data);
tr.html(`
<td>
${data.post.firstName}
</td>
<td>
${data.post.lastName}
</td>
<td>
${data.post.userId}
</td>
<td>
<div id="postId">
${data.post.id}
</div>
</td>
<td>
Here
</td>
<td>
${data.post.status}
</td>
<td>
<input type="button" class="btn btn-success" value="Approve" id="approveBtn-${trIndex}">
<input type="button" value="Send to Moderation" class="btn btn-primary" id="moderateBtn-${trIndex}">
</td>
`)
});
});
Due to reputation I can't make this a comment it looks like you have a dynamic id
disapproveBtn-<%= i %>
Your event listener is looking at disapproveBtn not each individual one
<% if(post.status === 1){ %>
<input type="button" class="btn btn-danger disapproveButton" value="Disapprove" id="disapproveBtn-<%= i %>">
<input type="button" class="btn btn-primary" value="Send to Moderation" id="moderateBtn-<%= i %>">
and then alter your event listener to be
$(".disapproveButton").click(function (e) {
I want to be clear on what you're expecting:
The user clicks the disapprove button inside a table row
The row changes, and should now contain an approve button
The user clicks the approve button, and something happens
The reason nothing happens when they click the approve button is that all your event listeners are created when the page first loads. The approve button is created after the page loads, and so it does not have an event listener.
I would recommend that you always have an 'approve' button in each row when the page loads, but just hide it with CSS (display:none) until the disapprove button has been clicked.
Otherwise, you will need to set an event listener on each approve button when it is created.
Related
I perform an ajax call that stores some data and adds a row in a table.
In this row there is a delete button at the end so you are able to instantly delete the row you created if you want.
For some reason when I click the delete button I get redirected to the deleteurl of the ajax call I use to delete the data from the database. When I reload the page and press the delete button it works fine.
Anyone knows why this is happening?
The row that is being added:
<tr>
<td>test</td>
<td>
<form class="deleteBuildingForm" method="POST" action="http://127.0.0.1:8000/buildingimage/42" accept-charset="UTF-8">
<input name="_method" type="hidden" value="DELETE">
<input name="_token" type="hidden" value="EEV90wmDNLMd8hg9ilh6zdDAjVShXW9bfOCXdvml">
<button type="submit" class="btn btn-danger">
<i class="far fa-trash-alt"></i>
</button>
</form>
</td>
</tr>
My jquery code:
$('.deleteBuildingForm').on('submit', function(e) {
e.preventDefault();
axios.delete($(this).attr('action'), []).then(response => {
$(this).closest('tr').remove();
$('.successMessages').hide();
});
});
I think the problem is that your new rows do not have the event handlers bound to them because they were dynamically created.
Event binding on dynamically created elements?
Try adding the event handler to the document, which will always exist.
$(document).on('submit','.deleteBuildingForm' ,function(e) {
e.preventDefault();
axios.delete($(this).attr('action'), []).then(response => {
$(this).closest('tr').remove();
$('.successMessages').hide();
});
});
Using laravel, I have a list of user details obtained from the database with edit and remove button at the end of each record. When i click the remove button, the particular record gets removed, but when I added a modal such that when the delete button is clicked, a model appears, but adding the functionality to the confirmation "Yes" button of the modal got tricky, as it deleted the first record no matter which user i need to delete. How do i get the clicked user to be deleted when the modal button is clicked?
I have tried to assign each button the id of the current row.
#foreach($admins as $admin)
<tr>
<td>{{$admin['id']}}</td>
<td>{{$admin['name']}}</td>
<td>{{$admin['email']}}</td>
<td>
<button type="button" class="btn btn-block btn-danger" data- toggle="modal" data-target="#modal-danger" id="{{$admin['id']}}">Remove</button>
</td>
</tr>
#endforeach
<!-- The Button From Modal -->
<button type="button" class="btn btn-outline">Remove</button>
I did it with JS. You can show your modal with $('#modal-danger').modal('show')
So you can add a onClick event to your button that fill a hidden input.
Your button that make the modal appear:
<button type="button" class="btn btn-block btn-danger" onClick="showModal({{$admin['id']}})">Remove</button>
Your hidden input (somewhere in your page):
<input type="hidden" id="id-to-remove" />
Your button from modal:
<button type="button" class="btn btn-outline" onclick="realRemove()">Remove</button>
Your JS:
function showModal(id) {
$('#id-to-remove').val(id);
$('#modal-danger').modal('show');
}
function realRemove() {
$('#modal-danger').modal('hide');
var id = $('#id-to-remove').val();
alert('You can now remove ID ' + id + ' from your database!');
}
This should work
Since you are using jQuery you can use attribute method to get the current clicked user id and pass to the URL:
Your HTML button class
$(".my-btn").click(function(){
var userID = $(this).attr("data-user");
if (typeof userID !== typeof undefined && userID !== false) {
if(userID.length > 0) {
// There you go the user id of the clicked user
console.log(userID);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="my-btn" data-user="user_id_123">Remove</button>
I suggest you to refer the following URL for your further questions regarding attr method https://www.w3schools.com/jquery/html_attr.asp
make a global variable to store the target id and assingn the id to it when clicking the button on the target row
<button type="button" class="btn btn-block btn-danger" data- toggle="modal" data-target="#modal-danger" id="{{$admin['id']}}" onClick=someFunction({{$admin['id']}})>Remove</button>
target_id=0
function someFunction(id) {
target_id=id
}
and then make another function to trigger when clicking on the remove button in the model and from that access the global variable for the target id
that's the optimal way to do it as I can think cheers.
My HTML I'm having controls inside table as :-
<tr ng-repeat="r in MyTblDataList">
<td>
<input id="chkBoxClass" type="checkbox" class="checkbox checkbox-inline" ng-model="r.BoardID" />
</td>
<td>
<input id="txtClass" type="text" class="form-control" ng-model="r.BoardName" value="{{r.BoardName}}" disabled />
</td>
<td>
<input id="btnEditClass" type="button" class="btn-xs btn-info" value="Edit" ng-click="EditUpdateChange('btnEditClass','btnUpdateClass','txtClass',true)" />
<input id="btnUpdateClass" type="button" class="btn-xs btn-success" value="{{btnUpdate}}" ng-click="UpdateClass('btnEditClass','btnUpdateClass','txtClass', r.BoardID )" hidden />
<input id="btnDeleteClass" type="button" class="btn-xs btn-danger" value="Delete" />
</td>
I'm using my function to show/Hide and Disable the textbox:-
$scope.EditUpdateChange = function (btnEditID, btnUpdateID, txtEditID, value) {
if (value) {
$('#' + btnEditID).hide();
$('#' + btnUpdateID).show();
}
else {
$('#' + btnEditID).show();
$('#' + btnUpdateID).hide();
}
//$('#' + txtEditID).prop('disabled', !value);
$(this).closest('tr').disabled = !value;
}
My problem is even though I click on Edit button in second or third row. My first row always go enable and disable. Can't figure out what I'm doing wrong. Also is there a better way of doing this using Angular?
For hiding and showing elements in angular, I think you should use the built-in directives ng-show, ng-hide or ng-if.
As the name suggests, ng-show and ng-hide show or hide the element based on the expression provided. Note that they are still in the DOM, they just aren't visible right now. ng-if insert or remove the element from the DOM, instead of showing or hiding.
For disabling the row, you can use the ng-disabled directive.
So, in your code, you could use:
<tr ng-disabled="!r.BoardID"> <!-- Didn't test, but I think this will disable the whole row, including the checkbox, so you may want to move the ng-disabled to the input itself -->
<input id="btnEditClass" type="button" class="btn-xs btn-info" value="Edit" ng-click="EditUpdateChange()" ng-hide="r.BoardID" />
<input id="btnUpdateClass" type="button" class="btn-xs btn-success" value="{{btnUpdate}}" ng-click="UpdateClass()" ng-show="r.BoardID" />
</tr>
In general, I think you don't really need to use JQuery when developing an Angular application.
Edit 1
The status you want then:
At first, edit and delete button are available and the textbox is disabled
When edit button is clicked:
Enable the textbox
Show the update button
Hide the edit button
Alright, so the code for this would be like that:
Row in html
<tr ng-repeat="r in MyTblDataList">
<td>
<input id="chkBoxClass" type="checkbox" class="checkbox checkbox-inline" ng-model="r.BoardID" />
</td>
<td>
<input ng-disabled="!r.isEditing" id="txtClass" type="text" class="form-control" ng-model="r.BoardName" value="{{r.BoardName}}"/>
<!-- Will disable on null, false and undefined -->
</td>
<td>
<input ng-click="onEdit($index)" ng-if="!r.isEditing" id="btnEditClass" type="button" class="btn-xs btn-info" value="Edit"/>
<!-- $index is a variable provided by ng-repeat -->
<!-- Similar as above, but will be inserted in the DOM instead of disabled. -->
<input ng-click="onUpdate($index)" ng-if="r.isEditing" id="btnUpdateClass" type="button" class="btn-xs btn-success" value="{{btnUpdate}}"/>
<!--
If you want to use show/hide, you would use:
Edit btn: ng-hide="r.isEditing"
Update btn: nh-show="r.isEditing"
-->
<input id="btnDeleteClass" type="button" class="btn-xs btn-danger" value="Delete" />
</td>
</tr>
variable and functions needed in JS
function onEdit(index){
MyTblDataList[index].isEditing = true;
}
function onUpdate(index){
// You may want to do something with the new data, maybe some validation or so
MyTblDataList[index].isEditing = false;
}
When updating the data in the controller, the change should be reflected in the view. To ilustrate this, I have created a Plunker with your code. In this plunker:
I use vm as syntax (you can search about this, but it is a better aproach to link the data to the controller through var vm = this instead of accessing the scope directly)
Made one field editable at one time
If you leave without clicking the Update button, the changes are discarted.
I have choosed to use the ng-if instead of ng-show and ng-hide to select what to show because as ng-if remove the content from the HTML, it remove the watchers manteined by Angular. Note that if there is an excesive amount of watchers, performance is affected.
I am trying to write a feature where a table data is generated from a database along with buttons like editing that particular row. The data is generated through a foreach from laravel. One of these buttons is called Edit User.
When the Edit User is clicked a form div will be .toggle('show') which will show the form.
Now I think the problem is the buttons have the same id for the toggle so when I press the second, third and so on buttons the form doesn't toggle.
Here is my script.js
$(document).ready( function() {
$("#form1").hide();
$("#form2").hide();
$("#createuser1").click(function() {
console.log('Create user button clicked');
$("#form2").hide();
$("#form1").toggle('slow');
});
$("#edituser1").click(function() {
console.log('Edit user button clicked');
$("#form1").hide();
$("#form2").toggle('slow');
});
});
//start of checkuser
function fetchUser(field, query) {
console.log('The field is ' + field + ' and the userid is ' + query);
}
my html file (main.blade.php)
<tbody>
#foreach($users as $user)
<tr>
<td>{{$user->userid}}</td>
<td>{{$user->firstname}}</td>
<td>{{$user->lastname}}</td>
<td>{{$user->username}}</td>
<td>{{$user->password}}</td>
<td>
#if($user->status == 0)
Inactive
#elseif($user->status == 1)
Active
#endif
</td>
<td>
<input class="btn btn-danger btn-inverse" type="button" value="Inactive" />
<input name="edituser" type="button" onclick="fetchUser('edituser', {{$user->userid}})" id="edituser1" class="btn btn-success btn-inverse" value="Edit User"/>
</td>
</tr>
#endforeach
</tbody>
This is the part where it toggles the forms (also part of main.blade.php)
<div class="container" id="form1">
#include('create')
</div>
<div class="container" id="form2">
#include('edit')
</div>
I have only included parts of the code to avoid chunks of unrelated code. But feel free to ask for any more details.
Help me solve the part where the other edit buttons doesn't toggle the edit user form.
I think it is better not to have inline click event handler if you have already a click handler in your code.
Change the id to a class:
<tbody>
#foreach($users as $user)
<tr>
<td>{{$user->userid}}</td>
<td>{{$user->firstname}}</td>
<td>{{$user->lastname}}</td>
<td>{{$user->username}}</td>
<td>{{$user->password}}</td>
<td>
#if($user->status == 0)
Inactive
#elseif($user->status == 1)
Active
#endif
</td>
<td>
<input class="btn btn-danger btn-inverse" type="button" value="Inactive" />
<input name="edituser" type="button" data-id="{{$user->userid}}" class="btn btn-success btn-inverse editUser" value="Edit User"/>
</td>
</tr>
#endforeach
</tbody>
Then change your js this way:
$(document).ready( function() {
$("#form1").hide();
$("#form2").hide();
$("#createuser1").click(function() {
console.log('Create user button clicked');
$("#form2").hide();
$("#form1").toggle('slow');
});
$(".editUser").click(function() {
console.log('Edit user button clicked');
var id = $(this).attr('data-id');
fetchUser('edituser', id);
$("#form1").hide();
$("#form2").toggle('slow');
});
});
//start of checkuser
function fetchUser(field, query) {
console.log('The field is ' + field + ' and the userid is ' + query);
}
This way you can reuse the code for all the edituser buttons, you have a much more readible code, you don't have two different click event handler and you don't loose the id of the single user to be passed to the fetchUser function
Well, as I see it, you have two options. Unique ids are a must. I'm assuming your userids are unique, so I'd recommend using them as suffixes to create unique ids for your elements.
First option: Create a unique form for each user that is opened when Edit User is clicked.
Second option: Create a generic form that is populated with the user information when Edit User is clicked.
The first is simpler, but the second with be more efficient. Here is example code of the second solution. Main HTML:
<div class="container" id="main">
<!-- ... -->
<input type="button" onclick="fetchUser('edituser', {{$user->userid}}, {{$user->firstname}}, {{$user->lastname}})" class="btn btn-success btn-inverse" value="Edit User" />
<!-- ... -->
</div>
Edit form HTML:
<div class="container" id="form2">
<input id='editFormFirstName' />
<input id='editFormLastName' />
<input id='editFormPassword' />
</div>
And JS:
function fetchUser(field, userid, firstname, lastname) {
$('#editFormFirstName').val() = firstname;
$('#editFormLastName').val() = lastname;
$('#editFormPassword').val() = "";
}
I am using a table in which each row has three buttons(save, edit, delete). On edit button i want to hide it and want to show save button, also want ot make name column editable.
On save button i want to hide it, and want to show edit button. the html code is bellow.
<table>
<tr>
<td class="editablecontent">Name</td>
<input data-edit type="button" value="Edit">
<input data-save type="button" value="Save" class="savevarients">
<input data-delete type="button" value="Delete">
</tr>
<tr>
<td class="editablecontent">Name</td>
<input data-edit type="button" value="Edit">
<input data-save type="button" value="Save" class="savevarients">
<input data-delete type="button" value="Delete">
</tr>
<tr>
<td class="editablecontent">Name</td>
<input data-edit type="button" value="Edit">
<input data-save type="button" value="Save" class="savevarients">
<input data-delete type="button" value="Delete">
</tr>
</table>
i am using this jquery code but the problem is when i am showing save button it shows i all table, and each row become editable. i want this only on one particulaar row.
My js code is bellow.
'click [data-edit]': function(event) {
event.preventDefault()
$(event.target).hide();
$(".editablecontent").attr('contenteditable', true);
$(".savevarients").show();
},
'click [data-save]': function(event) {
event.preventDefault()
$(event.target).hide();
$(".editablecontent").attr('contenteditable', false);
Replace:
$(".editablecontent").attr('contenteditable', true);
$(".savevarients").show();
with:
$(event.target).parent().find(".editablecontent").attr('contenteditable', true);
$(event.target).parent().find(".savevarients").show();
You can use jQuerys DOM traversal methods to find the nearest td to the button which was clicked and base all selectors on that using find(). Try this:
'click [data-edit]': function(event) {
event.preventDefault()
var $button = $(event.target).hide();
var $td = $button.closest(".editablecontent").attr('contenteditable', true);
$td.find(".savevarients").show();
},
'click [data-save]': function(event) {
event.preventDefault()
var $button = $(event.target).hide();
$button.closest(".editablecontent").attr('contenteditable', false);
}
Use jQuery's $.siblings() function, for example:
$(event.target).siblings(".editablecontent").attr('contenteditable', true);
$(event.target).siblings(".savevarients").show();
I would begin the function by defining the target element:
function(event) {
$target = $(event.target);
$target.hide();
$target.siblings(".editablecontent").attr('contenteditable', true);
$target.siblings(".savevarients").show();
event.preventDefault();
}