jQuery replaceWith() callback function to update things - javascript

I am using jQuery replaceWith() method to replace some content from the html. Its working fine. But I want to change the data attribute value once replaceWith() has been done.
So basically I am getting this from my ajax response
UpdatedItem = '<li data-cart-key="XXX" data-item-name="Test" data-item-price="$111.00" data-item-key="XXX"><span class="cart-action-wrap"><a class="edit-cart-item" data-cart-item="XXX" data-cart-key="XXX" data-cart-action="edit">Edit</a><a class="remove-cart-item" data-cart-item="XXX" data-cart-key="XXX" data-cart-action="remove">Remove</a></span></li>';
Now I am using replaceWith() here like this
$( 'ul.custom-contents' ).find( 'li.updated' ).replaceWith( UpdatedItem );
Here I wanted to use methods like update data attribute value, remove class, add class after replaceWith() has been done.
So can someone tell me is there any way available to do this? Any help and suggestions would be really appreciable. Thanks

you can solve like this.
UpdatedItem =
'<li data-cart-key="" data-item-name="Test" data-item-price="$111.00" data-item-key="XXX">updated</li>';
divElement = document.createElement("div");
divElement.innerHTML = UpdatedItem;
element = divElement.firstElementChild;
$("ul.custom-contents").find("li.updated").replaceWith(element);
element.setAttribute("data-item-name", "myValue");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<ul class="custom-contents">
<li class="updated">old</li>
<li class="">old</li>
<li class="">old</li>
</ul>
<script src="app.js"></script>
</body>
</html>

You can create a jQuery object inside replaceWith, do the operations and return it. Use .find() for nested elements:
$( 'ul.custom-contents' ).find( 'li.updated' ).replaceWith( fucntion(){
let obj = $(UpdatedItem)
obj.addClass("..")
obj.data("cart-key", "..")
obj.data("item-name", "..")
obj.removeClass("..")
//Find <a> with class "edit-cart-item"
obj.find("a.edit-cart-item").addClass(...)
obj.find("a.edit-cart-item").data("item-name", "..")
return obj;
});

Related

Bootstrap data-id not passing value

In my code I have
<script>
$(document).on('click', 'a#coin', function(){
// get month
var val = $(this).attr('data-id');
$.post('alert.php', {coin: val}, function(data){
console.log(data);
});
});
</script>
This is the data toggle link for the modal
<a id="coin" href="#" data-id="BTC" data-toggle="modal" data-target="#alertmodal"><i class="fa fa-bell fa-lg" title="Set Alert for BTC" style="color:orangered"></i></a>
And in alert.php I simply have
$coin = $_POST['coin'];
echo $coin;
The modal is popping up fine its just not passing the data-id value
Unsure as to what Im doing wrong
More code added
<?php
require('alert.php');
?>
<html><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<script>
$(document).ready(function(){
$("#liveprices").load("liveprices.php");
setInterval(function() {
$("#liveprices").load("liveprices.php");
}, 5000);
});
</script>
</head><body>
The function discussed here is loaded at the end of the document
Says bootstrap.min.js requires Jquery although jquery is loaded right
above it
By default bootstrap uses jQuery slim version. Slim version do not have $.ajax and related functions. Use the jQuery full version.
Use this jQuery
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
Below is the comment from the slim version with the features removed
/*! jQuery v3.2.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */
After a discussion over the chat regarding the requirements, we came to a conclusion that PHP is not at all required in this case and simple jQuery does the trick:
Requirements:
If you look at this screenshot
you will see a list of coin names with an alarm icon ..
When the relevant alarm icon is clicked I want it to pop up a modal and just assign and echo a variable value ( which will be the coin ) BTC etc
Later on a form will be added which ideally will have that data added to a hidden field ready for submission
Solution (one approach):
JS FIDDLE
Relevant code changes:
$(document).on('click', 'a.coin', function(){
var val = $(this).attr('data-id'), modal = $('div#test-modal');
console.log(val);
modal.find('.modal-title').html('Get alerts for ' + val);
modal.find('.modal-body .alert-notification').html('Get alert notifications when ' + val + ' breaks strong support / resistance lines');
modal.modal('show');
});
Since you are using document.on('click'), the $(this) may be somewhat confused. I might try $(event.target).closest('a#coin') in place of $(this) and see if it helps:
$(document).on('click', 'a#coin', function(event) {
var val = $(event.target).closest('a#coin');
console.log(val);
});

Javascript Object forEach is not a function

Hi Im trying to access the child nodes of a selected element, but the browser tells me that that object doesn't have a foreach function. What should I do for me to access the child elements. I dont want to use jquery instead I want to use native, for experiment purpose.
here is my code:
var el = document.querySelector('ol');
el.children.forEach(function(childEl) {
console.log(childEl);
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<ol contenteditable oninput="">
<li>press enter</li>
</ol>
</body>
</html>
Node.children is dom collection, not an real array so it doesn't have array methods like forEach(need to fix the case also).
So one commonly used solution is to call the array methods with the context as the html collection
var el = document.querySelector('ol');
[].forEach.call(el.children, function(childEl) {
console.log(childEl);
})
<ol contenteditable oninput="">
<li>press enter</li>
</ol>
Another way(similar) is to convert the collection to an array first(using Array.slice()) then call array methods on it
var el = document.querySelector('ol'),
array = [].slice.call(el.children);
array.forEach(function(childEl) {
console.log(childEl);
})
<ol contenteditable oninput="">
<li>press enter</li>
</ol>

How to get substring using Dojo and javascript

Good Day,
I am a newbie learning Javascript & Dojo and I typically learn by picking apart other parts of running code.
I am confused as to how to get a substring value from the following code (from the ArcGIS Sandbox):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Query State Info without Map</title>
<script src="http://js.arcgis.com/3.6/"></script>
<script>
dojo.require("esri.tasks.query");
dojo.require("esri.map");
var queryTask, query;
require([
"esri/tasks/query", "esri/tasks/QueryTask",
"dojo/dom", "dojo/on", "dojo/domReady!"
], function(
Query, QueryTask,
dom, on
){
queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5");
query = new Query();
query.returnGeometry = false;
query.outFields = ["SQMI","STATE_NAME","STATE_FIPS","SUB_REGION","STATE_ABBR","POP2000","POP2007","POP00_SQMI","POP07_SQMI","HOUSEHOLDS","MALES","FEMALES","WHITE","BLACK","AMERI_ES","ASIAN","OTHER","HISPANIC","AGE_UNDER5","AGE_5_17","AGE_18_21","AGE_22_29","AGE_30_39","AGE_40_49","AGE_50_64","AGE_65_UP"];
on(dom.byId("execute"), "click", execute);
function execute(stateName) {
query.text = dom.byId("stateName").value;
//execute query
queryTask.execute(query, showResults);
}
function showResults(results) {
var s = "";
for (var i=0, il=results.features.length; i<il; i++) {
var featureAttributes = results.features[i].attributes;
for (att in featureAttributes) {
s = s + "<b>" + att + ":</b> " + featureAttributes[att] + "<br>";
}
s = s + "<br>";
}
dom.byId("info").innerHTML = s;
}
});
</script>
</head>
<body>
US state name :
<input type="text" id="stateName" value="California">
<input id="execute" type="button" value="Get Details">
<br />
<br />
<div id="info" style="padding:5px; margin:5px; background-color:#eee;">
</div>
</body>
</html>
All I would like to do is pick apart the input (in this case the id="stateName" which is the word California).
So a silly example would be substituting the following code to get the first 10 characters of when someone types in 'California is on the west coast'
query.text = dom.byId("stateName").substring(0,10);
This is really so I can support other queries but I figured if I can do a substring on this input then it is really the same anytime when I query other attributes.
Thanks in advance for a newbie !
You need to get the innerHTML of your DOM element
query.text = dom.byId("stateName").value.substring(0, 10);
As Thomas Upton correctly pointed out the correct form would be:
dom.byId("stateName").value.substring(0, 10);
apparently the following also works
dom.byId("stateName").value.substr(0, 10);
As noted in comments, a call to .value will deliver what you need. Substring is a method on the string prototype See here. However, dom.byId returns a domNode. You don't want the substring of the domNode itself, you want the substring of the text value of the domNode. On inputs this is easily done with .value and is commonly done with .textContent and .innerHTML as well.

Wrap tr and td around data from ajax call in jQuery

I was wondering how i can add a new tr and td wrapped around data received from a ajax call? The following doesn't work.
$.get('/edit/'+course_id, function(data){
///add class to current tr
$('#course_'+course_id).addClass( "info" );
$('<tr><td>'+data+'</td></tr>').insertAfter('#course_'+course_id);
});
Any help would be much appreciated.
Thanks
You can add that to a table element. I think in IE, it needs to be attached with tbody.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<script src="jquery.js"></script>
<script>
$(document).ready(function () {
var data='some HTML';
$('<tr><td>'+data+'</td></tr>').insertAfter('#course');
});
</script>
</head>
<body>
<table>
<tbody>
<tr id="course"><td></td></tr>
</tbody>
</table>
</body>
</html>
(really) difficult to answer without the HTML markup, but this might be a binding problem :
maybe you can try
var successCourse = function(courseId) {
return function(data) {
///add class to current tr
$('#course_' + courseId).addClass("info");
$('<tr><td>' + data + '</td></tr>').insertAfter('#course_' + courseId);
};
};
$.get('/edit/'+course_id).done(successCourse(course_id));
The neatest way is probably...
$.get('/edit/' + course_id, function() {
// do whatever else you need to do
var formatted = $('<tr/>').append($('<td/>', { html: data }));
formatted.insertAfter('#course_' + course_id);
});
This saves you from the mess of writing html tags in as strings and having to remember to close them etc, by letting jQuery do pretty much everything for you.
Here's an example on jsFiddle which shows it working. Hope this helped!

Efficient way of finding index of row?

I am getting the index of a row by doing this:
row.parent().children("tr").index(row)
Is there a more efficient way to find the index? I have hundreds of rows so it is killing my performance that I have to select all rows just to find the index.
How about row.prevAll().length?
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" charset="utf-8" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
console.log($("tr").index($("#my")));
})
</script>
</head>
<body>
<table border="0" cellspacing="5" cellpadding="5" id="tbl">
<tr><th>Header</th></tr>
<tr><td>Data</td></tr>
<tr id="my"><th>Header</th></tr>
<tr><th>Header</th></tr>
<tr><td>Data</td></tr>
</table>
</body>
</html>
Hope that helps. Cheers.
Id attribute is the most fastest way to parse any html. You could provide all your rows with an Id.
Although the index method will determine the index among of the siblings elements, which could be faster
row.parent("tr").index();
see this example http://jsfiddle.net/shNrS/
If you are getting the reference to the row somehow (click handler etc) than there is no additional overhead in looking up that element, just .index() it and profit (although watch out for multiple tbody elements which are valid but would add complexity to your script)
If you are indexing all tr elements at runtime, might as well cache it in jquery data for future use!
The fastest way here is probably using plain javascript:
function getRowIndex(elem) {
var index = 0;
while (elem = elem.previousSibling) {
if (elem.tagName == "TR") {
++index;
}
}
return(index);
}
Working demo: http://jsfiddle.net/jfriend00/y4anN/
If you had to do this repeatedly on a large table that wasn't changing dynamically, then you could just pre-number the rows once with a custom attribute and from then on, all you'd have to do it retrieve the custom attribute from any row.
You would pre-number all the rows with a custom attribute like this:
function numberRows(table) {
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
rows[i].dataIndex = i;
}
}
And, then you can just obtain the index number from any given row like this:
row.dataIndex
Working demo: http://jsfiddle.net/jfriend00/CR2Wk/

Categories

Resources