jQuery replace multiple texts - javascript

I need some advice for my text replacement using jQuery. I have a template that looks like this and builds a shoppingcart:
{foreach from=$cart.products item=product}
<div class="product">
<span class="product-image"><img src="{$product.cover.small.url}"></span>
<div class="product-details">
<h2 class="name-header">{$product.name}</h2>
<div class="product-quantity-details">
<span class="quantity">{$product.quantity}</span>
This will give me a container for each product, there are more elements after and before. I have some buttons that can increase or decrease the quantity (.product-quantity-details .quantity). I use jQuery to send an AJAX request:
document.getElementById('link1').addEventListener('click', function(ev){
ev.preventDefault();
var html ;
$.ajax({
url: this.href,
type: "GET",
dataType: "html",
success: function(data) {
html = $(data).find('.product-quantity-details .quantity').html();
console.log(html);
$(".product-quantity-details .quantity").text(html);
}
});
});
The server returns a HTML representation of the whole cart (including the other items not shown in the code above). I cannot simply replace the container with the response, because there are images loaded and they don't appear if I use jQuery.replaceWith(). So currently I only can update one quantity.
Is there a way to update each quantity, so get an array of values from $(data).find('.product-quantity-details .quantity').html(); where I can iterate trhough and replace the exisiting text in the HTML?
Or is there a better way to achieve my gaol (update any amount of quantities in my HTML).
I thought of simply using html = $(data).find('.product-quantity-details .quantity');, is there a guarantee that this array has the order of the HTML elements?

simply use, I have not encountered any case where html elements order is not maintained. Also you have index property which will give the position number.
html = $(data).find('.product-quantity-details .quantity');

Related

Load static HTML file and split into array by class

I have been working on this for days and I get close but not all the way. Most of the SO answers I have found, help me get the file contents loaded into a div or a variable but it doesn't let me then do querySelectorAll on it. So, what I need to do is load the file and then break it up into an array based on a class. Without further ado, the code:
content.txt:
<h3 class="chapter">Chapter 1</h3>
<p>Lorem</p>
<h3 class="chapter">Chapter 2</h3>
<p>Lorem</p>
Loading JS:
$.ajax({
url: "content/content.txt",
cache: false,
crossDomain: true,
success: function(html){
var div = document.createElement("div");
div.innerHTML = html;
var chapters = div.querySelectorAll('chapter');
alert(chapters.length);
}
});
Expected Result:
['<h3 class="chapter">Chapter 1</h3><p>Lorem</p>',
'<h3 class="chapter">Chapter 2</h3><p>Lorem</p>']
So this loads the file (confirmed) and I have the html in a variable. I try loading it into a dynamic DIV in the DOM to do a querySelectorAll but all it returns is {}. If I dump the innerHTML all of my content is there.
I know I am mixing vanilla JS with jQuery, but I am unsure of the proper jQuery way to go about this. Any thoughts?
The selector chapter will match all your <chapter> elements. There is no such element in HTML and there is no such element in your text file. That is why nothing matches.
align="chapter" is invalid HTML. chapter is not a valid value for the align attribute, which is obsolete anyway.
Start by writing sensible HTML. Use a class to distinguish between types of div elements.
<div class="chapter">
For that matter, consider using the <section> element instead.
Then use a class selector (instead of a type selector):
div.querySelectorAll('.chapter');

jQuery text() and show() not working ( RoR application)

I want to implement a custom and simple check of the number of items that I have in the cart.
First, I load my page with a place holder div in one of my menu elements:
<div id="items_count" style="display:none;">(count)</div>
Then in my javascript file (application.js) I have the following code:
$(document).ready(function () {
$items_count_element = $("#items_count");
if ($items_count_element.length > 0 )
{
$.ajax({
url: '/get_items_count',
type: 'GET',
dataType: 'json',
success: function (response) {
// Construct the new string to display
items_count_new_content = "(" + response.items_count + ")";
// Printout to verify that we point to the correct div
alert($("#items_count").text());
// Verify the new string to display
alert(items_count_new_content);
// Empty the div element and replace the content with the new string
$("#items_count").empty().text(items_count_new_content);
// Remove display : none
$("#items_count").show();
}
});
}
});
The AJAX requested is executed with success, and the alerts display the expected text ( "(count)" and lets's say "(3)", which means i have 3 items in the cart ).
But $("#items_count").empty().html(items_count_new_content); and $("#items_count").show(); seem to not work at all, even if the functions are simple enough. Moreover, I've used them many times in the past with success...
I've tried to replace text() with html() with no success.
Any ideas what may be the problem here ?
Thanks
In jQuery, you can change a value with val:
$("#items_count").empty().val(items_count_new_content);
After debugging, i noticed that i had 2 menus on the page instead of one ( the normal menu and the sticky menu ). So my problem was the usage of the idas the selector my element. This caused that the jQuery replaced the content only for the sticky menu ( Which is invisible in the top of the page ), since we are supposed to have unique ids for each element in the DOM.
I fixed my issue by replacing $("#items_count") by $(".items_count_div")
I hope it'll help whoever encounter similar problem.

Make jQuery Search Filter use a Data attribute instead of whole DIV content

I have a KanBan board style app that shows Order records. I am trying to implement a Search filter using JavaScript and jQuery. THe goal is to filter out and hide all records that do not match the search number with the Order Number on a record.
So far I have a working example however I feel it can be improved possibly?
Here is my working JSFiddle Demo: http://jsfiddle.net/jasondavis/d7hj0ssv/1/
So basically it;s very simple....
It when the search form is submitted, it hides all Order records
It then uses this line $('.box:contains("'+txt+'")').show(); where txt is the search term. So after hiding all records, it display: block on any DIVs that match the search term.
$('.box:contains("'+txt+'")') is where my concern is. I believe it searches the whole entire Order record DIV for a matching string?
Each Order DIV looks like this code below so $('.box:contains("'+txt+'")') is searching this whole entire block of content for each order I believe which just looks bad performance wise!...
<div class="box card-record ui-sortable-handle" data-order-id="5430" data-order-number="100005054" data-order-item-id="145" style="display: block;">
<div class="alert-message warning">
<div class="ordernumber">Order #100005054</div>
<div class="orderid">Order ID: 5430</div>
<div class="itemid">Item #145</div>
<div>Date Created: 2015-06-23 00:27:22</div>
<div>Date Modified: 2015-06-23 00:27:22</div>
<div>some order data here</div>
View Order Item
</div>
</div>
In the DIV HTML above you might notice that each Order record also has a data attribute data-order-number="100005054" which I think might be better to use for the search if possible?
Below is my jQuery JavaScript code that handles the Search input and filtering out the DIVs based on the search term:
$(function() {
// Search filter to hide and show order cards mtching the search order number
$('#search').click(function(){
$('.box').hide();
var txt = $('#search-criteria').val();
$('.box:contains("'+txt+'")').show();
});
$('#searchclear').click(function(){
$('.box').show();
$('#search-criteria').val('');
});
});
If the search field is the order-number then yes, using the data-attribute would greatly improve your apps response time. You would use the jQuery .filter(function) method:
$('#search').on('click', function() {
$('.box').hide().filter(function() {
return $(this).data('order-number') == $('#search-criteria').val().trim();
}).show();
});
DEMO
If you want to target the div with that data, you can use the attribute selector syntax. This isn't terribly performant, but it should be faster than the :contains pseudo selector.
$('.box[data-order-number="'+txt+'"]').show();
or
$('.box[data-order-id="'+txt+'"]').show();
Some of your elements don't seem to have data-order-number in the fiddle, so I've used the id for the example. Not sure on the specifics between the two.
http://jsfiddle.net/47m7p2am/
The other option is to generate unique IDs or shared classes.
id="order-number-100005054" class="order-id-5418"
This would be much faster to look up, and the ideal solution if you can edit the HTML output.
Something like:
$('#order-number-' + txt).show();

Finding and Executing / Extracting embedded JavaScript from AJAX result using jQuery

I'm performing an AJAX request to get a generated html page. I want to find a specific div in the result and inject it into the page where the request came from. I also want to include embedded script or script links which may be inside this div. Here is a simple sample of the page I want to get with AJAX
<html>
<head>
<script>alert("don't want this")</script>
</head>
<body>
<div id='findMe'>
<p>Some content</p>
<script>alert("want only this")</script>
</div>
<script>alert("don't want this")</script>
</body>
</html>
So I only want to extract the div with ID findMe. Here's what I have in the page that's doing the request
<script>
$(document).ready(function(){
$.ajax({
url: "ajax.htm",
success: function(data){
$(data).filter("#findMe").appendTo("#output");
},
dataType: "html"
});
});
</script>
<div id='output'></div>
But the script tag is missing and no alert appears. It seems to get taken out of the div. If I do
console.log($(data))
I can see each of the script tags as a document fragement, but how to I know which one was in the div before it was popped out?
You can try:
$(data).find('#findMe').appendTo('#output');
OR
$('<div/>').append(data).filter("#findMe").appendTo("#output");
Append data to a demo div (not exists in DOM) and make filter over that.
I think instead of .filter(), which filters the current jQuery collection, you have to use .find():
$(data).find("#findMe").appendTo("#output");
But I am unsure whether the script tag will be executed or not..
I had to treat the result as XML. Find the element I'm looking for in the XML object using jQuery .find(), select the actual node (array pos 0), convert the contents of the node to a string, and inject into the output div. This is the only method I've found that executes scripts only contained in the target div.
$.ajax({
url: "ajax.htm",
success: function (data){
var node = $(data).find("#findMe")[0];
if(node.xml)
{
$("#output").html(node.xml)
}
else if(new XMLSerializer())
{
$("#output").html((new XMLSerializer()).serializeToString(node));
}
},
dataType: "xml"
});

How to add html img to page from javascript but not hardcode it in javascript

I use ajaxForm to upload image. On success upload I add uploaded image to div on the page:
$("#ajaxUploadForm").ajaxForm({
iframe: true,
dataType: "json",
...
success: function (result) {
$("#imageList").prepend('<img src=' + result.message + '/>');
Now I was thinking that it is not smart to put this hardcoded <img/> tag in javascript code.
What is the best way to put image but not use img tag in prepend() function?
i would not have any problem with that... unless you are worried about invalid url that could break the tag...
you could use simple javascript
var img = new Image();
img.src = result.message;
$("#imageList").prepend(img);
IMHO that is the best way, there's no need to change anything. If you don't want to dynamically append/detach, you could have an existing img as a placeholder and just change its src attribute when you wanted to change it:
<img id="placeholder" src="initial/path" />
$("#placeholder").attr("src", result.message);
But since you're dealing with an image list, as your code suggested, I think your original solution is more appropriate for your case. If you ever decide to remove an image or sort the list or whatever, you can selected them using $("imageList img").
Edit: OTOH if you have a very complex structure, that you want to code in HTML but also need to make dynamic copies of it, you can use clone as an alternative:
<div id="model" style="display:none">complex markup goes here</div>
$("#model").clone().attr("id",anotherID).appendTo(target).show();
Use a template. For instance:
<div style="display:none">
<!-- This div contains all your templates -->
<img src="about:blank" class="classesYouNeed" id="uploadSuccess">
</div>
and then use javascript:
$("#ajaxUploadForm").ajaxForm({
iframe: true,
dataType: "json",
...
success: function (result) {
var img = $('#uploadSuccess')
.clone()
.attr('id', somethingElse)
.attr('src', result.message)
$("#imageList").prepend(img);
})
})
There are jQuery templating frameworks out there that will make this much easier.

Categories