How can I change icon on AJax response? - javascript

I have an anchor tag with an icon inside that I want to change it on click.
So, using Ajax I tried as below:
HTML
<a id="#pl-esong234" class="social-button-song" title="Add in playlist" onclick="addInPlaylistSongs(234, 1)">
<i class="ion-plus all-btn-icon"></i>
</a>
JS
function addInPlaylistSongs(track, id) {
$.ajax({
type: "POST",
url: baseUrl+"/requests/manage_playlists.php",
data: "id="+track+"&playlist="+id+"&type=4&token_id="+token_id,
cache: false,
success: function(html) {
$('#pl-esong'+track).append('<i class="ion-checkmark all-btn-icon"></i>');
}
});
}
I tried also:
//2nd try
$('#pl-esong'+track+' i').after('<i class="ion-checkmark all-btn-icon"></i>').remove();
//3rd try
$('#pl-esong'+track+' i').after(html).remove();
//4th try
$('#pl-esong'+track+' i').replaceWith(html);
I tried to console log on success and everything is correct, the html response is <i class="ion-checkmark all-btn-icon"></i> and the select item is #pl-esong234.
Why I'm not able to change the icon inside my anchor element?

Remove the hash from the id. It is using by the selectors to find the matched tag.
# - used to find by id.
. - user to find by class
<a id="pl-esong234" class="social-button-song" title="Add in playlist" onclick="addInPlaylistSongs(234, 1)">
<i class="ion-plus all-btn-icon"></i>
</a>
and call html().
$('#pl-esong'+track+' i').html('<i class="ion-checkmark all-btn-icon"></i>');

Related

Anchor text falling outside of <a> tag after Ajax append

I am loading content from a URL through Ajax and appending the content to a container. When the content is appended, the anchor text falls outside of the <a></a> tag.
Everything is appending correctly, and the code on the URL requested is absolutely fine with no issues.
// url: https://example.com/index.html
<div class="data-row__classes data-row__item">
<img src="http://localhost/wp-content/uploads/2017/10/english.png" alt="icon">
<span>English</span>
</div>
// appended HTML after ajax request to https://example.com/index.html
<div class="data-row__classes data-row__item">
<img src="http://localhost/wp-content/uploads/2017/10/english.png" alt="icon">
<span>English</span>
</div>
// note the malformed anchor tag 2 lines above
I am not sure exactly how to describe this; but I can't find any other instances of this problem online. The HTML markup is absolutely fine on the requested page; does anyone know what may be scrambling it? Specifically the link and nothing else?
Full Ajax
$('.class-table__nav__favorites').on('click', function(e) {
var class_table_height = $('.class-table__results').outerHeight();
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
$.ajax({
url: cml_theme.ajaxurl,
type: 'get',
data: {
action: 'favorites_only_off',
paged: $('.class-table__foot__nav').data('page')
},
beforeSend: function(result) {
$('.class-table__results').css('height', class_table_height);
$('.class-table__results').empty();
$('.class-table__results').append('<div class="class-table__loading"></div>');
},
success: function(result) {
$('.class-table__results').css('height', 'auto');
$('.class-table__loading').remove();
$('.class-table__results').append(result);
$('.class-table__foot').show();
}
});
}
});
The code which it takes from the WordPress action: 'favorites_only_off' is exactly as described above with the example url (example.com/index.html).
Malformed HTML in a previous <a> that closed the opening tag with <a href="" ... /> instead of <a href="" ... >

Ajax and Mongodb, use _id

I have a test project using express.js that displays all items in a mongo database on a webpage. Each database entry is displayed on the page with a button to delete it.
-each i in docs
p ----------------------
p <strong>Name: #{i.name}
p <strong>Type: #{i.type}
p <strong>Amount: #{i.quantity}
p <strong>ID: #{i._id}
input(type = 'button', value ="delete item", id='delete')
I want the button to send a DELETE request to /api/item/_id
My script is as follows
script(type='text/javascript').
$(document).ready(function() {
$("#delete").click(function() {
$.ajax({
type: 'DELETE',
url: '/api/item/' + this._id
}).done(function(result) {
});
});
});
This is not sending the desired request. How would I go about passing the _id from the item to the button?
If I set the URL to a know _id, like below, it works and the item is deleted
url: '/api/item/56f3e800d6f24d0819e43fcc'
Thanks in advace
Use data- attribute
Html
<input type="button" id="delete" data-id="mongo id here" />
JS
$.ajax({
type: 'DELETE',
url: '/api/item/' + this.attr('data-id')
})
Also you'd better use class instead of id="delete"
If I understand your looping code you appear to be assigning the same HTML ID attribute to each button:
input(type = 'button', value ="delete item", id='delete')
That makes for invalid HTML (only one item can have a given ID). You can make the delete attribute a class where its legal to have more than one item with the same class.
If you console.log(this) when any of these buttons are clicked what is this referring to? What _id do you get? Do you get the same _id regardless of what button is clicked?

X-Editable Bootstrap field loads only on the first link

I'm using Bootstrap X-Editable along with bootstrap-wysihtml5.
I have a comment list on every post page with an edit link under each comment.
But I can only edit the first comment on the last (the newest submitted comment) and the rest simply don't load the X-Editable field.
$('#note').editable({
validate: function(value) {
if($.trim(value) == '')
return 'Value is required.';
},
type: 'wysihtml5',
title: 'Edit Comment',
placement: 'top',
send:'always',
ajaxOptions: {
dataType: 'json',
type: 'post'
}
});
$('#pencil').click(function(e) {
e.stopPropagation();
e.preventDefault();
$('#note').editable('toggle');
});
And the HTML
<div id="note"
class="note"
data-type="wysihtml5"
data-toggle="manual"
data-pk="{{ $each_comment->id }}"
data-placement="top"
data-url="{{ url($each_comment->post_id . '/comment/update') }}">
{!! $each_comment->comment !!}
</div>
<a href="#"
id="pencil"
class="pencil"
data-type="wysihtml5"
data-toggle="manual"
data-pk="{{ $each_comment->id }}"
data-placement="top"
data-url="{{ url($each_comment->post_id . '/comment/update') }}">
<i class="icon-pencil" style="padding-right: 5px"></i>[edit]
</a>
UPDATE
I made some changes, I added a pen class to the edit link
[edit]
And I call it with a.pen
('a.pen').click(function(e) {
e.stopPropagation();
e.preventDefault();
console.log($('#note').attr("data-pk"));
$('#note').editable('toggle');
});
Now all edit links are loading the X-Editable field but they're all showing the same comment with id 142 which is the latest submitted comment.
console.log prints the same id whenever I click on the edit link.
From $('#note').editable( it looks like you're dynamically generating content with duplicate id.
id selector always returns the first match because the rule is, id should be unique in a document .
You should be using class, name or similar attributes that is allowed to be repeated instead of id.
So using class the code should be something like following:
$('.pencil').click(function(e) {
e.stopPropagation();
e.preventDefault();
$(this).prev('.note').editable('toggle');
});

Passing parameters to on click jquery event from dynamic list of anchor tags

I'm working on a list of elements in my asp.net mvc project. Each element is part of a ul, and the list elements are generated based on a list in my model.
I'm trying to add a delete button to each of these elements, but I'm struggelig a bit with how to make these elements unique, for jquery to pass the correct parameters to my action later on.
Each element has its own guid, but I can't figure out how to pass these along to the .on('click') jquery handler.
Here's the relevant part of my razor view:
<ul class="panel-tasks ui-sortable">
#foreach (RunModel run in Model.PlannedRuns)
{
<li>
<label>
<i class="fa fa-edit"></i>
<!--<i class="fa fa-ellipsis-v icon-dragtask"></i>-->
<span class="task-description">#run.Name</span>
<span class="sl-task-details">#run.RunTask</span>
<span class="sl-task-unit">#run.ConveyanceId</span>
<span class="sl-task-location">#run.Operation.WellContract.Location, #run.Operation.WellContract.Name</span>
</label>
<div class="options">
</i>
</div>
</li>
}
</ul>
And here's my javascript:
<script type="text/javascript">
$("#del").on("click", function (runId) {
$.ajax({
url: "#Url.Action("DeleteRun", "Planning")",
type: "GET",
dataType: "json",
data: { runId: runId },
error: function (msg) {
// Error handling
},
success: function (msg) {
// Success handling
}
});
});
</script>
I do realize I could add onClick to the anchor tag passing along the id as a parameter there, but I was hoping using jquery would do the trick, like mentioned above. Also, is there a recommended approach for doing tasks like this when several html elements use the same method?
You can use a data-* parameter on the delete button specific to that instance which you can then retrieve on click. You also need to make the delete button use a class attribute, otherwise they will be duplicated in the loop. Try this:
<div class="options">
<i class="fa fa-trash-o"></i>
</div>
$(".del").on("click", function (e) {
e.preventDefault();
var runid = $(this).data('runid');
$.ajax({
url: "#Url.Action("DeleteRun", "Planning")",
type: "GET",
dataType: "json",
data: { runId: runId },
error: function (msg) {
// Error handling
},
success: function (msg) {
// Success handling
}
});
});
The answers using data- attributes are elegant and do the job. However, I would like to propose a (slightly) different approach:
#foreach (RunModel run in Model.PlannedRuns)
{
<li id="#run.Id">
...........
</li>
}
Inside the a elements, set your del id as class.
$(".del").on("click", function () {
var runid = $(this).parent().id;
//..............
});
The advantages of this solution:
Your li elements have an id which can be used by other JavaScript functions as well
No need to play around with attributes (be careful as Firefox is very picky with data- attributes)
Additionally, your delete a elements won't have duplicate ids.
You can access the item clicked with $(this) in a click event (and most events).
$(".del").on("click", function () {
var runId = $(this).data("runId");
$.ajax({
url: "#Url.Action("DeleteRun", "Planning")",
type: "GET",
dataType: "json",
data: { runId: runId },
error: function (msg) {
// Error handling
},
success: function (msg) {
// Success handling
}
});
});
and insert the id as data-runId= in the HTML:
<i class="fa fa-trash-o"></i>
As the delete button is a boookmark only (#) the only effect it may have is to move the page to the top. To stop that add an event parameter and call preventdefault() on it. (or simply return false from the event handler).
$(".del").on("click", function (e) {
e.preventDefault();
And as Rory McCrossan points out, you should not have duplicate ids on your delete buttons (use a class). Dupe ids will actually work on most browsers, but are considered a bad thing :)

AJAX not working with Knockout.JS

For some reason, I cannot get an AJAX function
$('#queueSubmit').on('click', function() {
$.ajax({
type: 'POST',
url: nodeApiUrl + 'twitter/update_status/',
contentType: 'application/json',
data: JSON.stringify({'status': $('#queuedTweet').val() }),
dataType: 'json',
error: $.osf.handleJSONError
});
});
to be called when I click the button with id queueSubmit. This is the knockout code that generates the buttons and content.
<div id = "foo">
<!-- ko foreach: tweets -->
<input id = "queuedTweet" data-bind="value: tweet"/>
<a class="btn btn-primary" id = "queueSubmit" >
Send
</a>
<a id = "removeFromQueue" data-bind = "click: $parent.removeTweet, value:index" class="btn btn-danger">
Delete
</a>
</br>
<!-- /ko -->
</div>
It does not register that the button is being clicked. I believe it has something to do with the bindings but not sure how to remedy. Any help would be appreciated!
You want do do this instead of your current implementation:
<a class="btn btn-primary" data-bind="click: $parent.queueSubmit">Send</a>
Then in your viewModel do this:
self.queueSubmit = function() {
$.ajax({
type: 'POST',
url: nodeApiUrl + 'twitter/update_status/',
contentType: 'application/json',
data: JSON.stringify({'status': $('#queuedTweet').val() }),
dataType: 'json',
error: $.osf.handleJSONError
});
};
Use knockout bindings any time you can. If a native binding doesn't exist, create a custom binding.
IDs are supposed to be unique, but you are creating them within a ko foreach loop. That means you actually have an array of "queueSubmit" IDs. jQuery assumes you will only have one, so it always retrieves the first one in the list.
You can see this in action by using the native JavaScript functions:
document.querySelector("#queueSubmit"); // <== returns the first one in the list
document.querySelectorAll("#queueSubmit"); // <== return the array of elements with that id
document.querySelectorAll("#queueSubmit")[n]; // <== returns the element at index 'n'
Duplicating IDs is a really bad idea (I've always been surprised that this is even allowed, but it is).
That leads to the question "why are you using an ID"? If you are going to replicate it like this, then either make the IDs unique or replace them with a class. (The class option is much better).
Even better, like #Cameron suggested, use a click binding to a function inside your KO ViewModel instead. This will also have the added benefit of automatically passing the bound data item (the current instance of the foreach loop) to the function.
<div id = "foo">
<!-- ko foreach: tweets -->
<input id = "queuedTweet" data-bind="value: tweet"/>
<a class="btn btn-primary" click="$parent.queueSubmit" >
Send
</a>
<a id="removeFromQueue" data-bind="click: $parent.removeTweet, value:index" class="btn btn-danger">
Delete
</a>
</br>
<!-- /ko -->
And then in your ViewModel:
self.queueSubmit = function(item) { // <== current tweet is passed in automatically
$.ajax({
type: 'POST',
url: nodeApiUrl + 'twitter/update_status/',
contentType: 'application/json',
data: JSON.stringify({'status': item.tweet }), // <== use the item, not jQuery
dataType: 'json',
error: $.osf.handleJSONError
});
};
You can learn more about the click binding at the KO website
You can't use IDs in this way. You should register a click binding.

Categories