Sorting dynamic elements in isotope - javascript

I'm building a list of ships, using jQuery's $.each loop and a JSON file created in Google Sheets (Tabletop.js), and trying to sort them with Isotope.js.
jQuery creates the list without any issues. However, when I click on my button to sort the elements via Isotope, nothing happens.
When I hardcode the elements into my HTML page, Isotope sorts everything no problem.
I've looked all over the Internet and couldn't find an answer.
The loop with a callback to another function that fetches my data from a spreadsheet. #port is a div in my HTML where everything is going.
Here's the code I'm working with.
function showInfo(data, tabletop) {
var shipData = tabletop.sheets('data').all();
var items=[];
$.each(shipData, function(i) {
//Put each ship in the port ^__-
var ship = "<div class=\"ship\"><div class=\"row\"><p class=\"name font-lg\">" + shipData[i].name + "</p><p class=\"cruise-line font-xs\">" + shipData[i].line +"</p><div class=\"ship-photo col-md-9 col-sm-9\"><img src=\"img/" + shipData[i].img + "\" class=\"img-responsive\"></div><div class=\"ship-info col-md-3 col-sm-3\"><div class=\"row\"><div class=\"header font-xs col-sm-4 col-xs-4\">Launched</div><div class=\"header font-xs col-sm-4 col-xs-4\">Length</div><div class=\"header font-xs col-sm-4 col-xs-4\">Tonnage</div></div><div class=\"row\"><div class=\"year font-lg col-sm-4 col-xs-4\">" + shipData[i].launchYear +"</div><div class=\"length font-lg col-sm-4 col-xs-4\">" + shipData[i].length + "'</div><div class=\"weight font-lg col-sm-4 col-xs-4\">" + shipData[i].tonnage + "</div></div></div><div class=\"ship-info col-md-3 col-sm-3\"><div class=\"row\"><div class=\"header font-xs col-sm-6 col-xs-6\">Max capacity</div><div class=\"header font-xs col-sm-6 col-xs-6\">Crew</div></div><div class=\"row\"><div class=\"max-passenger font-lg col-sm-6 col-xs-6\">" + shipData[i].maxCapacity + "</div><div class=\"crew font-lg col-sm-6 col-xs-6\">" + shipData[i].crewCapacity + "</div></div></div></div>";
items.push(ship);
});
$port.append(items)
}
Here's my Isotope sorting code:
// init Isotope
$('#port').isotope({
itemSelector: ".ship",
layoutMode: 'vertical',
getSortData: {
name: '.ship'
}
})
// bind sort button click
$('#sorts').on( 'click', 'button', function() {
var $this = $(this);
var sortValue = $this.attr('data-sort-value');
$('#port').isotope({
sortBy: sortValue
});
});
Here's my HTML:
<div class="compare">
<h3>How the ships compare</h3>
<div id="sorts" class="button-group">
<button class="button" data-sort-value="name">name</button>
<button class="button" data-sort-value="length">length</button>
<button class="button" data-sort-value="weight">weight</button>
<button class="button" data-sort-value="passengers">passenger</button>
<button class="button" data-sort-value="original-order">clear</button>
</div>
</div>
<div id="port"></div>
JSFiddle demo. One list is generated in JS while the other is made in HTML.

Two issues to fix.
Change #sorts to this:
<button id="sort" data-sort-value="name">Click to sort</button>
and your data function to this:
$.each(data, function (i) {
$('.port').append("<li><div class='name'>" + data[i] + "</div></li>");
});

Related

Increasing space between rows in table dynamically created from js function

I have a JS function in a modal that is creating a table in a grid from data being returned from a controller action. It works fine, however I wish there was a little more space between the rows. I have tried adding &nbsp and it doesn't seem to do the trick.
Can anyone give me a solution to this? Below is a picture of the modal, my JS function and the markup for the modal.
modal:
JS function:
$("button[name='paramsBtn']").click(function () {
/* Grabs ID from col selected */
var $col = $(this).closest('.row').find('.requestId');
var jobRequestId = $col.data('id');
var nameType = $col.data('name');
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId, "name" : nameType},
success: function (results) {
$modal = $('#paramsModal');
$modal.modal("show");
var name = [];
var value = [];
var arr = results;
//loop through arr created from dictionary to grab key(s) and value(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
//name += key;
//value += results[key];
name.push(key);
value.push(results[key])
//Remove previous rows
$("div[name='params']").remove();
for (var i in name) {
//Adding parameters as rows
$('<div class="col-md-6 text-break" name="params"> ' + name[i] + '</div>'+ '<div class="col-md-6 text-break" name="params">' + value[i] + '</div>').insertAfter($('#modalGridHeader'));
}
}
}
}
});
});
markup for modal:
<div class="modal fade" id="paramsModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header modal-header-primary" style="margin-bottom:-16px;">
<a class="btn btn-xs btn-primary pull-right" data-dismiss="modal" aria-label="Close"><span class="glyphicon glyphicon-remove"></span></a>
<h4 class="modal-title" id="modalTitleText">Job Parameters</h4>
</div>
<div class="modal-body" style="height:250px;">
<div class="list-group">
<div class="row list-group-item list-group-item-heading container divTableHeading" style="width:inherit; margin-bottom:0px;" id="modalGridHeader">
<div class="col-md-6 font-weight-bold"> Parameter(s): </div>
<div class="col-md-6 font-weight-bold"> Value(s): </div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The line that is adding the rows is:
$('<div class="col-md-6 text-break" name="params"> ' + name[i] + '</div>'+ '<div class="col-md-6 text-break" name="params">' + value[i] + '</div>').insertAfter($('#modalGridHeader'));
Here is where I have tried adding &nbsp. I have also tried adding margin-bottom:5px, but it looked very odd.
Thanks
Quick and dirty
In <div class="col-md-6 text-break" name="params"> add style="height:20px;".

How to properly display the checked attributes in another div with different styles?

I am very new to jQuery. The first part of the code is to check the inputs and after checked it should display the checked items the below format. How can do this with the help of jquery.
<ul class="approval approval_scrolltab mt-3">
<li>
<div class="approval--member">
<img src="assets/images/user.jpg" class="user--image" />
<div class="w-100">
<h6 class="approval--name">Name</h6>
<p>Initiator</p>
</div>
<div class="form-group">
<div class="checkbox">
<input name="one" type="checkbox" id="one" />
<label for="one"></label>
</div>
</div>
</div>
</li>
</ul>
After checked it should displays in this format.
<div class="col-xl-6 col-lg-6 col-md-6 offset-xl-1">
<h6 class="heading--form mb-2 mt-3 mt-sm-0">
User
</h6>
<ul class="approval approval_scrolltab mt-3">
<li>
<div class="approval--member">
<img src="assets/images/user.jpg" class="user--image" />
<div class="w-100">
<h6 class="approval--name">Name</h6>
<p>Initiator</p>
</div>
<a href="">
<span class="ic-close"></span>
</a>
</div>
</li>
</ul>
</div>
I tried like this.It was working fine for the names but got no idea how can display this user image attached with name and also there is a cancel icon too near the name.I am only being able to display name with this code.
<script>
$('input[type="checkbox"]').on('change', function () {
var name = $(this).attr('data-name');
var image = $(this).attr('data-image');
if ($(this).prop('checked')) {
$('#checked-names').append('<p data-name="' + name + '">' + name + '</p>');
$('#checked-images').append("<img src='image'")
} else {
$('#checked-names p[data-name="' + name + '"]').remove();
$('#checked-images').remove()
}
});
</script>
UPDATE
With this close button I want to remove this from checked list(which works great) as well as I want to uncheck this from checked in input.
$('body').on('click', '.ic-close', function() {
$(this).closest('li').remove()
$(this).closest('li').prop('checked',false) #didn't worked
});
This script below might be helpful for you. I only added an ID to the user-list and removed the a tag from the close button in your HTML. The JavaScript appends the HTML you wish with the name and the image to the list. If you click the close span, the item will be removed.
UPDATE:
To uncheck the checkbox by closing its user-list item, you have to add an attribute like data-name="Initiator" to the checkbox. In the JavaScript if have added two lines into the click listener of the ic-close item, see below.
$('input[type="checkbox"]').on('change', function() {
var image_url = $(this).closest( '.approval--member' ).find( 'img' ).attr('src');
var name = $(this).closest( '.approval--member' ).find( '.approval--name ~ p' ).text();
if($(this).prop('checked')) {
$('ul#user-list').append(
'<li id="' + name + '">' +
'<div class="approval--member">' +
'<img src="' + image_url + '" class="user--image" />' +
'<div class="w-100">' +
'<h6 class="approval--name">Name</h6>' +
'<p>' + name + '</p>' +
'</div>' +
'<span class="ic-close">Close</span>' +
'</div>' +
'</li>');
} else {
$('ul#user-list #' + name).remove();
}
$('body').on('click', '.ic-close', function() {
var name = $(this).closest('li').find('.approval--name ~ p' ).text();
$('input[data-name="' + name + '"]').prop( "checked", false );
$(this).closest('li').remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="approval approval_scrolltab mt-3">
<li>
<div class="approval--member">
<img src="assets/images/user.jpg" class="user--image" />
<div class="w-100">
<h6 class="approval--name">Name</h6>
<p>Initiator</p>
</div>
<div class="form-group">
<div class="checkbox">
<input data-name="Initiator" name="one" type="checkbox" id="one" />
<label for="one"></label>
</div>
</div>
</div>
</li>
</ul>
<div class="col-xl-6 col-lg-6 col-md-6 offset-xl-1">
<h6 class="heading--form mb-2 mt-3 mt-sm-0">
User
</h6>
<ul id="user-list" class="approval approval_scrolltab mt-3">
</ul>
</div>
Simply check if you really need jQuery, in 2020 the pure Javascript have the majority of the jQuery fonctions : http://youmightnotneedjquery.com/
You can get the checked attribute via an event like this :
var checkbox = document.querySelector('[type="checkbox"]');
// Event Listener:
checkbox.addEventListener('change', function(event) {
alert(event.target.checked);
if(event.target.checked) {
// Do want do you want when checked
}
});
I don't understand very well what you expected but I hope that it could help you.

Event firing twice in kendo collapsible

I have an app the uses the Progress JSDO to load data and, using the foreach method of the jsdo, append the data to three different lists in kendo collapsible panels depending on the status of one of the fields. For some reason, the lists are being appended twice in the code and I can't figure out why. I would appreciate another set of eyes on my code to help me get to the bottom of this mystery.
Here is the controller for the view (this is all wrapped in an IIFE with some other code, but this is the relevant section.):
app.scanBarcode = {
viewModel: new ScanViewModel(),
onShow: function () {
app.JSDOSession.addCatalog(app.JSDOSettings.catalogURIs);
app.locJSDO.fill();
$("#list-button").unbind().click(function () {
app.goToScanFail();
});
app.scanBarcode.getCurrentReport();
},
onHide: function () {
var reportJSDO = app.reportJSDO,
writeOutReport = app.scanBarcode.writeOutReport;
reportJSDO.unsubscribe('afterFill', writeOutReport);
},
getCurrentReport: function () {
var reportJSDO = app.reportJSDO,
writeOutReport = app.scanBarcode.writeOutReport;
//Fill the JSDO from db and call function to display the data
reportJSDO.subscribe('afterFill', writeOutReport);
reportJSDO.fill();
},
writeOutReport: function (jsdo, success, request) {
var date = app.getDate();
jsdo.foreach(function (report) {
var reportDate = report.data.STAMP_DT,
completed = "<span class='glyphicon glyphicon-ok'></span>",
notCompleted = "",
span;
if (reportDate == date) {
if (report.data.STAMP_TM == null) {
span = notCompleted;
$("#uncompleted-list").append(
"<li class='list-group-item'>" +
span + " " +
report.data.LOCATION_ID +
' ' +
report.data.LOCATION_NAME +
"</li>"
);
} else {
span = completed;
$("#completed-list").append(
"<li class='list-group-item'>" +
span + " " +
report.data.LOCATION_ID +
' ' +
report.data.LOCATION_NAME +
"</li>"
);
}
$("#all-list").append(
"<li class='list-group-item'>" +
span + " " +
report.data.LOCATION_ID +
' ' +
report.data.LOCATION_NAME +
"</li>"
);
}
});
}
}
This is the html for my view:
<div data-role="view" data-title="Scan Location" data-reload="true" data-layout="views-layout" data-model="app.scanBarcode.viewModel" data-show="app.scanBarcode.onShow" data-hide="app.scanBarcode.onHide">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<h3 class="hassubtitle">Begin Scan:</h3>
<button class="btn btn-xlg btn-primary btn-block" data-bind="click: scan">Scan</button>
<button id="list-button" class="btn btn-lg btn-default btn-block">Skip</button>
</div>
<div class="col-xs-12 col-md-6 col-md-offset-3">
<div data-role="collapsible" id="completed-collapsible">
<h2>
Completed
</h2>
<div data-role="scroller" id="completed-list"></div>
</div>
<div data-role="collapsible" id="uncompleted-collapsible">
<h2>
Uncompleted
</h2>
<div data-role="scroller" id="uncompleted-list"></div>
</div>
<div data-role="collapsible" id="all-collapsible">
<h2>
All
</h2>
<div data-role="scroller" id="all-list"></div>
</div>
</div>
I'm the only web developer at my work and I have no one to ask here, so I really appreciate you all!

jquery append() is creating two div elements

I am adding div elements dynamically to the DOM using jquery append(). I have made a controller that takes json data using $http.get() and calls a function create_mission to add the divs to DOM. I have to create a div for every object of the json, so i have done it using a loop and iterating it for json.length times. But here two div elements gets created at every iteration.
Here is my controller
mission_vision_mod.controller('mission_visionCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.visiontext = "Here is the content of vision";
$scope.bkclr = ['bk-clr-one', 'bk-clr-two', 'bk-clr-three', 'bk-clr-four'];
$scope.progressbar = ['progress-bar-warning', 'progress-bar-danger', 'progress-bar-success', 'progress-bar-primary'];
$scope.missioncount = ['col-md-0', 'col-md-12', 'col-md-6', 'col-md-4', 'col-md-3', 'col-md-2.5', 'col-md-2'];
$http.get('m_id.json').success(function (data) {
$scope.missions = data;
$scope.len = data.length;
create_mission();
});
var create_mission = function () {
var i;
for (i = 0; i < $scope.missions.length; i++) {
$("#missionstart").append("<div id='" + $scope.missions[i].id + "' class='" + $scope.missioncount[$scope.missions.length] + "'></div>");
$("#missionstart").find("#" + $scope.missions[i].id + "").append("<div class='dashboard-div-wrapper " + $scope.bkclr[i] + "'></div>");
$("div#" + $scope.missions[i].id + "").find(".dashboard-div-wrapper").append("<h1>" + $scope.missions[0].missionInfo + "</h1>");
$("div#" + $scope.missions[i].id + "").find(".dashboard-div-wrapper").append("<div class='progress progress-striped active'></div>");
$("div#" + $scope.missions[i].id + "").find(".dashboard-div-wrapper").find("div").append("<div class='progress-bar " + $scope.progressbar[i] + "' role='progressbar' aria-valuenow='80' aria-valuemin='0' aria-valuemax='100' style='width: 80%'></div>");
$("div#" + $scope.missions[i].id + "").find(".dashboard-div-wrapper").append("<ul class='unorderedlist'></ul>");
}
}
}]);
The HTML file
<div class="content-wrapper" ng-controller="mission_visionCtrl">
<div class="container-fluid">
<div id="header-wrapper" class="container">
<div id="header" class="container">
<div id="logo">
<h1 class="page-head-line" id="visionh"><a>Vision</a></h1>
<p id="visionp"><a rel="nofollow">{{visiontext}}</a></p>
</div>
</div>
</div>
<div class="row" id="missionstart">
</div>
</div>
The json file
[{"id":1,"missionInfo":"mission"},{"id":2,"missionInfo":"mission1"},{"id":3,"missionInfo":"mission2"},{"id":4,"missionInfo":"mission3"}]
Since you have used angularjs, use a angularjs solution
<div class="content-wrapper" ng-controller="mission_visionCtrl">
<div class="container-fluid">
<div id="header-wrapper" class="container">
<div id="header" class="container">
<div id="logo">
<h1 class="page-head-line" id="visionh"><a>Vision</a></h1>
<p id="visionp"><a rel="nofollow">{{visiontext}}</a></p>
</div>
</div>
</div>
<div class="row" id="missionstart">
<div id="{{mission.id}}" ng-class="missioncount[missions.length]" ng-repeat="mission in missions">
<div class="dashboard-div-wrapper" ng-class="bkclr[$index]">
<h1>{{mission.missionInfo}}</h1>
<div class="progress progress-striped active">
<div class="progress-bar" ng-class="progressbar[$index]" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"></div>
</div>
<ul class="unorderedlist"></ul>
</div>
</div>
</div>
</div>
</div>
then
mission_vision_mod.controller('mission_visionCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.visiontext = "Here is the content of vision";
$scope.bkclr = ['bk-clr-one', 'bk-clr-two', 'bk-clr-three', 'bk-clr-four'];
$scope.progressbar = ['progress-bar-warning', 'progress-bar-danger', 'progress-bar-success', 'progress-bar-primary'];
$scope.missioncount = ['col-md-0', 'col-md-12', 'col-md-6', 'col-md-4', 'col-md-3', 'col-md-2.5', 'col-md-2'];
$http.get('m_id.json').success(function (data) {
$scope.missions = data;
$scope.len = data.length;
});
$scope.missions = data;
$scope.len = data.length;
}]);
Firstly, I found a possible typo in your javascript code.
$("div#" + $scope.missions[i].id + "").find(".dashboard-div-wrapper").append("<h1>" + $scope.missions[0].missionInfo + "</h1>");
I believe what you want is $scope.missions[i].missionInfo. Other than this, your code should be fine.
Secondly, in angular world, the normal way to iterate is to use ng-repeat (please see Arun's answer). Your view and controller shouldn't know each other, and they should communicate through your model.
Inside Loop try this code:
var div2=$("div></div>").addClass("dashboard-div-wrapper "+$scope.bkclr[i]);
div2.append("<h1>" + $scope.missions[0].missionInfo + "</h1>");
div2.append($("<div></div>").addClass("progress progress-striped active").append("<div class='progress-bar " + $scope.progressbar[i] + "' role='progressbar' aria-valuenow='80' aria-valuemin='0' aria-valuemax='100' style='width: 80%'></div>"));
div2.find(".dashboard-div-wrapper").append("<ul class='unorderedlist'></ul>");
var div1=$("<div></div>").id($scope.missions[i].id).addClass($scope.missioncount[$scope.missions.length]).append(div2);
$("#missionstart").append(div1);
Code not tested. Test it and let me know.

Script not flowing to first div only

Below is a script used to grab and spit out some of our data. The way it works is we create a variable then send it to the div id's located below.
function loadPregame() {
$.ajaxSetup({ cache: false });
$.getJSON("_schedule_" + seasontype + ".json",
function(data){
var game = data.gscd.g;
var status = game[gamenum].st;
//home team top nav
var homeTeamTop='<div class="homelogo col-md-5 col-sm-6 col-xs-12 pull-left">';
homeTeamTop+='<img src="logos/' + game[gamenum].h["ta"] + '.png" class="img-responsive" />';
homeTeamTop+='</div>';
homeTeamTop+='<div class="col-md-7 col-sm-6 col-xs-6 scorepad">';
homeTeamTop+='<span class="record score">' + game[gamenum].h["re"] + '</span>';
//homeTeam+='<br /><span id="homerank" class="rank"></span>';
homeTeamTop+='</div>';
// HOME TEAM
var homeTeam='<div class="homelogo col-md-5 col-sm-6 col-xs-12 pull-left">';
homeTeam+='<img src="logos/' + game[gamenum].h["ta"] + '.png" class="img-responsive" />';
homeTeam+='</div>';
homeTeam+='<div class="col-md-7 col-sm-6 col-xs-6 scorepad">';
homeTeam+='<span class="record score">' + game[gamenum].h["re"] + '</span>';
//homeTeam+='<br /><span id="homerank" class="rank"></span>';
homeTeam+='</div>';
// VISITOR TEAM
var visTeam='<div class="awaylogo col-md-5 col-sm-6 col-xs-12 pull-right">';
visTeam+='<img src="logos/' + game[gamenum].v["ta"] + '.png" class="img-responsive" />';
visTeam+='</div>';
visTeam+='<div class="col-md-7 col-sm-6 col-xs-12 scorepad pull-left">';
visTeam+='<span class="record score">' + game[gamenum].v["re"] + '</span>';
//visTeam+='<br /><span id="visrank" class="rank"></span>';
visTeam+='</div>';
document.getElementById("homeTeamTop").innerHTML=homeTeamTop;
//document.getElementById("visTeamTwo").innerHTML=visTeamTwo;
document.getElementById("visTeam").innerHTML=visTeam;
document.getElementById("homeTeam").innerHTML=homeTeam;
});
} //end function
What I can't seem to figure out is why the homeTeamTop won't proceed to my "HomeTeamTop" div. The others, which come after in progress have no issue. I've tried changing up the variable names and even redoing each manually. I then tried using the same info in the variables that work, but to no avail. <div id="visTeam"></div> and <div id="homeTeam"></div> which come next in progression print just fine. Is there a var_dump function as in PHP that I can use to see what's being rendered for homeTeamTop?
<div id="homeTeamTop"></div>
<div id="visTeam"></div>
<div id="homeTeam"></div>

Categories