Javascript string replace has no effect - javascript

I have the following structure:
<span class="h1">Color green</span>
<div class="swatchesContainer">
<img title="green" src="/"/>
<img title="blue" src="/"/>
</div>
Now I want to change the color in the in the span to the color which is stated in the titleof the image. (No I am not able to add a class with the color name)
I have tried te following code:
var product_name = jQuery(".h1").text();
jQuery(".swatchesContainer img").click(function(){
var selected_color = jQuery(this).attr('title');
var string;
console.log("String before: " + product_name);
jQuery('.swatchesContainer img').each(function(){
string = product_name.replace(jQuery(this).attr('title').trim(),' ');
console.log(jQuery(this).attr('title'));
})
console.log("String after: " + string);
jQuery(".h1").text(string + " " +selected_color);
});
I'm fetching all the title attributes from te images and replace them from te text in the same foreach function
But the new color keeps appending after the existing color
JSFiddle

There is a flaw in your logic. Inside the loop you are repeatedly overwriting the string variable:
string = product_name.replace(...)
At the end of loop you will have "Color green".replace("blue", " ") -> "Color green".
Change these lines:
var string;
// ...
string = product_name.replace(jQuery(this).attr('title').trim(),' ');
To these:
var string = product_name;
// ...
string = string.replace(jQuery(this).attr('title').trim(),' ');
Updated Fiddle
Having said all that, I would rather change the markup to this:
<span class="h1">Color <span class="chosen-color">green</span></span>
<div class="swatchesContainer">
<img title="green">
<img title="blue">
</div>
And overwrite the contents of .chosen-color instead of get/match/replace the entire text inside .h1. Your jQuery code will be reduced to one line.

Another approach would be:
var span = $('.h1');
$('.swatchesContainer img').on('click', function() {
var txtArr = span.text().split(' ');
txtArr[1] = this.title;
span.text( txtArr.join(' ') );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="h1">Color green</span>
<div class="swatchesContainer">
<img title="green" src="/"/>
<img title="blue" src="/"/>
</div>

Related

How can i replace html data with a json array using jquery and ajax

I'm trying to replace the data on a products page i'm working on using ajax. I've gotten the data from php as an array but when i try to use the each iterator on jquery on the last row from the json array is used. I'm assuming it replaces all the necessary html fields with each item from the json array instead of replacing just one field with one item.
Jquery code is below..the image source is gotten from the database and is supposed to replace the current image source
$.get('product2.php', function (data) {
// console.log(data);
var output = JSON.parse(data);
$.each(output, function () {
console.log(1);
var productname = this['name'];
var productImage = "data/" + this['image'];
var productPrice = this['unit_price'];
var productId = this['id'];
if (output) {
$('.productimg').attr('src', productImage);
}
});
console.log(output);
this is the html code
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img id='<?php echo "data/$row[id]"; ?>' class="productimg " height="300px"
src='<?php echo "data/$row[image]"; ?>' alt="IMG-PRODUCT">
<div class="block2-overlay trans-0-4">
<a href="#" class="block2-btn-addwishlist hov-pointer trans-0-4">
<i class="icon-wishlist icon_heart_alt" aria-hidden="true"></i>
<i class="icon-wishlist icon_heart dis-none" aria-hidden="true"></i>
</a>
<div class="block2-btn-addcart w-size1 trans-0-4">
<!-- Button -->
<button class="flex-c-m size1 bg4 bo-rad-23 hov1 s-text1 trans-0-4" data-id="1" data-name="product 1"
data-summary="summary 1" data-price="10" data-quantity="1" data-image="images/img_1.png">
Add to Cart
</button>
</div>
</div>
</div>
the page has 12 of this divs generated from another page after querying the database.
I'ts a personal project i'm trying to work on
here are some pictures
i hope this will be help you
$.get('product2.php', function (data) {
var html = '';
var obj = JSON.parse(data);
$.each(obj, function (key, value) {
var productname = value.name;
var productImage = "images/" + value.image;
var productPrice = value.unit_price;
var productId = value.id;
html += '<img class="productimg" height="300px" src="' + productImage + '">';
});
$('.productimg').html(html);
});
$('.productimg').attr('src', productImage);
This line of code will replace all your images with the last image in the array because you are using the same class for all <img> tags
instead use the following piece of code
$(image_id).attr('src', productImage);
where image_id should be the HTML id of the <img> tag
You could try to use JavaScript Dot notation, as JSON stands for JavaScript Object Notation, it works the same as any other JavaScript object.
This means that you can do this:
<script>
//Out JSON string:
var ProductJSON = {
"Productname": "Box of code",
"Price": 5.50,
"Weitght": 15,
"isMetric": true
}
//Putting it in HTML with JS (the ugly way)
document.write("ProductName: " + ProductJSON.Productname );
document.write("Price: " + ProductJSON.Price);
document.write("Weitght: " + ProductJSON.Weitght);
</script>
If I understand your code correctly, you are overwriting your variables. You could define your variables as an array, and looping through those to create new elements.
I hope this will nudge you into the right direction.
Using class as selector $('.productimg').attr('src', productImage); will change all image, because multiple tag's have the same class name, to change image of particular tag use id $('#'+productId ).attr('src', productImage);.

Fetch HTML element value from json stingrigy value using Javascript

I have object which i have converted using JSON.stingrify
{
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
}
From above i want to fetch "cropped_two", which is on
onchange=\"alertFilename(this.value,'cropped_two');
Here this.value will remain same, so if in case want to split the string .
I have tried via multiple ways by looping and other but in vain.
Anyone can help ?
Thanks in advance.
I think you just want the string? I guess this would work.
let o = {
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
};
const regex = /,(.*)\);/gm;
const match = regex.exec(o._originalElementInner);
console.log(match[1]);
you can use a search function to find "this.value" position, then use substring function from "this.value" position + 11 to the position of ")" witch seems to be the only ")" in the string.
If it is possible to use jQuery, you can follow this approach.
var obj = {"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "},
stringValue = '',
// This function will be called when the event change is triggered.
alertFilename = function(_, str) { stringValue = str;};
// Create the jQuery object and trigger the event change
// Finally remove the function from window object (This is just to remove an unsed function after execute it).
$(obj['_originalElementInner']).trigger('change'), (delete window['alertFilename']);
console.log(stringValue);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If there could be several onchange callbacks in your code, the following code will get the one that refers to alertFilename, it is also faster than regexp.
function extractSecondArg(text) {
// Define the pattern to look for.
const pattern = 'onchange=\"alertFilename(this.value,'
// Find the index of the pattern.
const patternIndex = text.indexOf(pattern);
if (patternIndex !== -1) {
// Find the closing parenthesis.
const patternEnd = ');';
const patternEndIndex = text.indexOf(patternEnd, patternIndex);
// Extract the second argument of the function.
return text.substring(patternIndex + pattern.length, patternEndIndex).replace(/["']+/g, '');
}
}
Here is an example of how to use it.
const json = {
"_originalElementInner": " <input type=\"file\" name=\"\" class=\"hidden\" id=\"file_input_two\" onchange=\"alertFilename(this.value,'cropped_two');\"> <!-- <img src=\"https://dxyz.com/tmp/5bd432ed2d8dd_img3.jpg\" alt=\"\" width=\"100%\" height=\"100%\"> --> "
};
// Extract element to search in.
const secondArg = extractSecondArg(json['_originalElementInner']);
console.log(secondArg)

How to split multiple string using jQuery or javascript?

I know this been posted here: how to split the string using jquery or javascript
but in my case have multiple strings. It's working in a single line of string but if it's in a multiple lines it repeats the day after year. and for some reason it display's only the first 'li' value. Is it possible to display it this way:
<ul>
<li>
<div class="date">
<p class='day'>23</p>
<p class='month'>05</p>
<p class='year'>2013</p>
</div>
</li>
<li>
<div class="date">
<p class='day'>25</p>
<p class='month'>07</p>
<p class='year'>2014</p>
</div>
</li>
<li>
<div class="date">
<p class='day'>01</p>
<p class='month'>05</p>
<p class='year'>2014</p>
</div>
</li>
</ul>
here is my code:
html
<ul>
<li><div class="date">23-05-2013</div></li>
<li><div class="date">25-07-2014</div></li>
<li><div class="date">01-05-2014</div></li>
</ul>
css:
.day{color:#ccc;}
.month{color:#ff0000;}
.year{color:green;}
script:
var data =$('.date').text();
var arr = data.split('-');
$(".date").html("<p class='day'>"+arr[0]+"</p>"+"<p class='month'>"+arr[1]+"</p>"+"<p cass='year'>"+arr[2]+"</p>");
jsfiddle:
demo
thanks Bon
You are getting the text from the first element, and changes all elements to contain the code for that. You need to loop through the elements and convert the content in each one.
You can use a callback function in the html method to do that, it will get the original HTML code from each element, and you return the new HTML code for that element:
$(".date").html(function(i, h) {
var arr = h.split('-');
return "<p class='day'>"+arr[0]+"</p><p class='month'>"+arr[1]+"</p><p class='year'>"+arr[2]+"</p>";
});
Demo: http://jsfiddle.net/Guffa/815c95jn/1/
(Note the difference in function, as this will get the HTML code in each element instead of the text. As long as there is no actual HTML markup in the elements, like in your example, there is no difference in the result.)
An alternative to splitting the text is to use replace:
$(".date").html(function(i, h) {
return "<p class='day'>" + h.replace("-", "</p><p class='month'>").replace("-", "</p><p class='year'>") + "</p>";
});
You only selected one .date, but you have to iterate over all of them, e.g. using $.each():
$(".date").each(function () {
var data = $(this).text();
var arr = data.split('-');
$(this).html("<p class='day'>" + arr[0] + "</p>" +
"<p class='month'>" + arr[1] + "</p>" + "<p class='year'>" + arr[2] + "</p>");
});
Adjusted Fiddle, and for reference: http://api.jquery.com/each/
Since the title asks about how to completed this with jQuery or Javascript (assuming vanilla JS) let me give a quick example of how this might be done without the need for jQuery:
var dates = document.querySelectorAll('.date');
var dateClasses = ['day', 'month', 'year'];
Array.prototype.forEach.call(dates, function(date){
var dateString = date.innerHTML;
var dateStringArray = dateString.split('-');
var content = "";
for(var i = 0; i < dateStringArray.length; i++){
var newDate = document.createElement('p');
newDate.classList.add(dateClasses[i]);
newDate.innerHTML = dateStringArray[i];
content += newDate.outerHTML;
}
date.innerHTML = content;
});
.day{color:#ccc;}
.month{color:#ff0000;}
.year{color:green;}
<ul>
<li><div class="date">23-05-2013</div></li>
<li><div class="date">25-07-2014</div></li>
<li><div class="date">01-05-2014</div></li>
</ul>

Splitting a html page based on <img> tag

HTML PAGE:
<div id="d"
<p>one</p>
<p>two</p>
<img class="select image" scr="something>
<p>SPLIT HERE<p>
<p>end</p>
</div>
Pseudo CODE:
var element = $("#d");
elemnet.split("img").such that =
split_one = <p>one</p><p>two</p>
split_two = <p>split here<p><p>end</p>
split_three = Name of img class i.e = select image
HTML PAGE may containg one or more image class inside a div?
Using split()
html = '<div id="d"<p>one</p><p>two</p><img class="select image" scr="something><p>SPLIT HERE<p><p>end</p></div>';
html.split(/<img class="(.*)"\sscr=[^<]+/);
Output:
["<div id="d"<p>one</p><p>two</p>", "select image", "<p>SPLIT HERE<p><p>end</p></div>"]
You may use exec() as well
matches = /(.*)<img class="(.*)"\sscr=[^<]+(.*)/g.exec(html);
Output:
matches[1] // <- "<div id="d"<p>one</p><p>two</p>"
matches[2] // <- "select image"
matches[3] // <- "<p>SPLIT HERE<p><p>end</p></div>"
Using replace(); if you want the order mentioned above, the expression below would reorder the capturing groups
html.replace(/(.*)<img class="(.*)"\sscr=[^<]+(.*)/g, "$1|$3|$2").split("|");
Output:
["<div id="d"<p>one</p><p>two</p>", "<p>SPLIT HERE<p><p>end</p></div>", "select image"]
Working jsBin
use regex
var element = $("#d").html();
var split = elemnet.split("/<img(.*?)>/");
use .nextAll() and .prevAll()
$("img").prevAll(); // Returns all the elements befor the image
$("img").nextAll(); // Returns all the elements after the image

Appending new container on click

I'm trying to learn HTML and Javascript/jQuery. If I have a container which holds a title, an image, a description and a number, then I want to create a new container with the exact same format (except the values will be different), how is this commonly done?
This is an example of the format I'm looking for in each item.
<li>
<div>
<div>
Image Name
</div>
<div>
<a href=URL>
<img src='image_url'>
</a>
</div>
<div>
Description
</div>
<div>
num_comment Comments
</div>
</div>
</li>
Do I just create a string and concatenate with the actual values for the image, then add that string to some variable I've saved called html_content, and then set the html value to html_content? Is that the common way of doing this or is there a better way?
EDIT
To give a better idea of what I'm currently doing, here's the javascript:
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
};
$('pics').html(html);
}
In jQuery you just have to use the append() function to add on to something.
You could do something like...
$('select element').append('<li><div>....etc.');
and where you want a different value you can use a variable.
You can use .clone() and create a copy of this, then iterate through the cloned object and change what you need:
var $objClone = $("li").clone(true);
$objClone.find("*").each(function() {
//iterates over every element. customize this to find elements you need.
});
To change the image source you can do:
$objClone.find("img").attr("src", "new/img/here.jpg");
Fiddle demoing the concept: http://jsfiddle.net/H9DnA/1/
You may find it useful to explore some of the JavaScript templating libraries. The essential idea is that you create a template of your markup:
<li>
<div>
<div>
{{name}}
</div>
<div>
<a href="{{url}}">
<img src="{{imageUrl}}">
</a>
</div>
<div>
{{description}}
</div>
<div>
{{comments}}
</div>
</div>
</li>
Then you merge it against some associated matching object and insert it into your document:
{ name: 'Image Name',
url: 'http://example.com',
imageUrl: 'http://example.com/image.jpg',
description: 'Description',
comments [ { text: 'Comment' } ]
}
function render(pics)
{
var theList = document.getElementByid("LIST ID");
for (var i in pics){
var listItem = document.createElement('li'); // Create new list item
var nameDiv = document.createElement('div'); // Create name DIV element
nameDiv.innerHTML = pics[i].name; // Insert the name in the div
var img = document.createElement('img'); // Create Img element
img.setAttribute('src',pics[i].src); // Assign the src attribute of your img
var imgDiv = document.createElement('div'); // Create Img Div that contains your img
imgDiv.appendChild(img); // Puts img inside the img DIV container
var descDiv = document.createElement('div'); // Create Description DIV
descDiv.innerHTML = pics[i].description; // Insert your description
listItem.appendChild(nameDiv); // Insert all of you DIVs
listItem.appendChild(imgDiv); // inside your list item
listItem.appendChild(descDiv); // with appropriate order.
theList.appendChild(listItem); // Insert the list item inside your list.
}
}
I think this will work just fine:
$('#button').click(function () {
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
$("ul").append(html);
}
}
// call render
});
I didn't do a test run on your code so there might be an error somewhere. My tweak adds this line $("ul").append(html); inside your loop

Categories