jQuery load .data to a child element - javascript

My index.html is here:
<tr class="activity_row" t-att-data-activity_id="activity.id">
<td>
<div>
<t t-if="duration != undefine">
<span class="pt_duration_line"><t t-esc="duration.split(':')[0] + 'h ' + (duration.split(':')[1] and duration.split(':')[1] + 'min' or '')"></t></span> <!-- call format_hour method of this screen -->
</t>
</div>
</td>
</tr>
For first tr tag the onclick action is:
this.$el.find(".activity_row").on("click", this.on_row_click);
on_row_click: function(event) {
var activity_id = $(event.currentTarget).data("activity_id");
if(activity_id) {
var activity = this.project_timesheet_db.get_activity_by_id(activity_id);
this.project_timesheet_widget.screen_selector.set_current_screen("add_activity", activity);
}
},
Here i am getting activity_id successfully. But Inside this row there is internal div which includes span as mentioned on top containing pt_duration_line class. And for this, onclick action is :
this.$el.find(".pt_duration_line").on("click", this.on_url_click);
on_url_click: function(event) {
var act_id = $(event.currentTarget).data("act_id");
if(act_id) {
var activity = this.project_timesheet_db.get_activity_by_id(act_id);
for this internal div I am not getting value of 'act_id' which I am getting for 'activity_id' for parent element row.
In brief: What to do if i want to get activity_id for the div resided in that row.
Thanks in advance

try this:
<tr class="activity_row" t-att-data-activity_id="activity.id">
<td>
<div>
<t t-if="duration != undefine">
<span class="pt_duration_line" t-att-data-act-id="activity.id"><t t-esc="duration.split(':')[0] + 'h ' + (duration.split(':')[1] and duration.split(':')[1] + 'min' or '')"></t></span> <!-- call format_hour method of this screen -->
</t>
</div>
</td>
</tr>
also, as other users mentioned, e and event are not the same, change to this:
this.$el.find(".pt_duration_line").on("click", this.on_url_click);
on_url_click: function(event) {
var act_id = $(event.currentTarget).data("act_id");
if(act_id) {
var activity = this.project_timesheet_db.get_activity_by_id(act_id);

Related

jQuery: Detect duplicate in select & show an alert

The code below has a select with three options. When you choose one of the options and click add the option is added to the table. If the user were try to choose the same option I need an alert or modal window to appear saying "Duplicates not allowed."
Anyone have an idea how to accomplish that?
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<select class="select-duc" id="keys">
<option></option>
<option>Allergies</option>
<option>Animals</option>
<option>Coughing</option>
</select>
<button type="button" id="add-user-code" class="btn btn-default pull-right" data-dismiss="modal">Add User Code</button>
<div class="col-sm-6 reset">
<div class="details-page-container two">
<h5>User Codes</h5>
<div class="table-container">
<table>
<tbody><tr>
<th><strong>Code</strong></th>
<th><strong>Description</strong></th>
<th><strong>Domain</strong></th>
<th><strong>Start Date</strong></th>
<th><strong>End Date</strong></th>
<th><strong>Delete</strong></th>
</tr>
<tr>
<td>01</td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td></td>
<td>Delete</td>
</tr>
<tr>
<td>02</td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td></td>
<td>Delete</td>
</tr>
<tr id="3rd-row" class="hideIT">
<td id="example"></td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td>12/01/2019</td>
<td><a data-toggle="modal" data-target="#myModal2" href="#">Delete</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Define an array, and
In your $("#add-user-code").click function:
Check if the value(which user selected) is already present in the array or not(To show the alert),
push the index/value to the array after adding it to your table(So that next time the condition fails and alert would show up).
Also, don't forget to remove items from the array whenever needed(User Starts again or item is removed from the table)/
I'd better just hide the duplicate option when the one is selected and show them back when/if its unselected, for better user experience.
Otherwise, you can make an array of selected values and loop through it when an option selected, something like this:
var selectedOptions = [];
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
if($.inArray(selectedKey, selectedOptions)) {
alert ("Duplicate values are not allowed");
} else {
selectedOptions.push(selectedKey);
}
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
});
});
Still, it has to be reset when options are unselected, I don't see multiple options in your snippet, though
You can create a function to return all the values to check whether the value the user wants to insert does not exits already
function getTableValues() {
return $('tr').find('td:first-child').map(function() {
return $( this ).text();
}).get();
}
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
if(!getTableValues().includes(selectedKey)) {
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
}
else {
alert('Duplicate not allowed');
}
});
I don't think you need the .click() bind inside of the .change() bind. Also, rather than using an alert, you could just make that option not available.
$("#add-user-code").click(function(){
$('#example').html('<span class="lbl">' + $('#keys option:selected').hide().text() + ' </span>');
$("#3rd-row").show();
$('#keys option:eq(0)').prop('selected', 'selected'); //set the select back to the blank option
});
Then if you click delete:
$('a').click(function() {
let example = $('#example .lbl').text().trim();
$('#keys option').filter(function() {return this.textContent === example; }).show();
$("#3rd-row").hide();
});
You shouldn't need an array or function to achieve what you're after.
https://jsfiddle.net/g9523ysz/
If you really need an alert:
$("#add-user-code").click(function(){
let option = $('#keys option:selected').text();
if (option) {
if ($('td').filter(function() { return $(this).find('.lbl').text().trim() === option; }).length){
alert('Duplicates not allowed.');
} else {
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + option + ' </span>');
}
}
});
I would suggest that if you can, use a more specific class for the span, like lbl-user-code. Then rather than having to check every single td you could:
if ($('.lbl-user-code').filter(function() { return this.textContent === option; }).length) { ... }
https://jsfiddle.net/9us4d08j/

How can i clone or add multiple ck editor on page

I want multiple textarea(ck editor) where user can input multiple data in it , i tried various function and methods of jquery like clone() and appendTo but the problem is they are cloning the textarea but ckeditor is not working, after cloning the textarea i am unable to wrote anything in it
Please help me with it.
This is what i tried
test1
http://jsfiddle.net/FADxv/793/
test2
http://jsfiddle.net/kbqjnecx/3/
Thanks
Add an id to each new textarea and manually initialize the editor using
CKEditor.replace(id [,config])
Something like:
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
var editorId = 'editor_' + x;
$(wrapper).append('<div> <textarea id="'+editorId+'" class="ckeditor" name="ck[]"></textarea>Remove</div>'); //add input box
CKEDITOR.replace(editorId, { height: 200 });
}
});
DEMO
Check this for cloning ckeditor.
Check this fiddle : http://jsfiddle.net/manektech/47htysb5/
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://cdn.ckeditor.com/4.5.4/standard/ckeditor.js"></script>
</head>
<body>
<div class="row hide_mail_id_domain">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>Option</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<textarea class="ckeditor" required="" name="question_option_1" ></textarea>
</td>
<td></td>
</tr>
</tbody>
</table>
Add More
</div>
</div>
<script>
var REMOVE = '';
var i=1;
$(document).ready(function () {
$('.add_more').click(function () {
var oneplus=i+1;
var tr_object = $('tbody').find('tr:first').clone();
// getting and renaming existing textarea by name.
$(tr_object).find('textarea[name="question_option_1"]').attr("name", "question_option_"+oneplus+"");
$(tr_object).find('input').val('');
$(tr_object).find('td:last').html('Remove');
$('tbody').append(tr_object);
//replace code
CKEDITOR.replace("question_option_"+oneplus+"");
// when i were clicking on add more during my testing , then extra cke-editor id also appending to DOM. so for removing other then first
// included below code
$('#cke_question_option_1').each(function() {
var $ids = $('[id=' + this.id + ']');
if ($ids.length > 1) {
$ids.not(':first').remove();
}
});
i=i+1;
oneplus++;
});
$(document).on('click', '.remove_more', function () {
var id = $(this).closest('tr').find('.id').val();
if (id != '') {
if (REMOVE != '') {
REMOVE = REMOVE + ',' + id;
} else {
REMOVE = id;
}
$('#id').val(REMOVE);
}
$(this).closest('tr').remove();
});
});
</script>
</body>
</html>

Toggle Selected Table Row Highlight on Button Click

I have a simple table with a Select button for each row that when clicked calls a PHP script to update a Session Variable with the ID of the selected Item. Here's the table:
<tr class="" id="PR9215">
<td>CODE A</td>
<td>Fresh Frust</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
<tr class="" id="PR9594">
<td>Oranges</td>
<td>Fresh Oranges</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
<tr class="" id="PR9588">
<td>MANGO</td>
<td>Fresh Mango</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
and here's the script that it calls:
$(document).ready(function() {
$('button.btn-success').click(function() {
var itemID = $(this).closest('tr').attr('id');
// Create a reference to $(this) here:
$this = $(this);
$.post('updateSelections.php', {
itemID: itemID,
selectionType: 'yes'
}, function(data) {
data = JSON.parse(data);
if (data.error) {
var ajaxError = (data.text);
var errorAlert = 'There was an error updating your selections - ' + ajaxError + '. Please contact Support';
$this.closest('tr').addClass("warning");
$('#alert_ajax_error').html(errorAlert);
$("#alert_ajax_error").show();
return; // stop executing this function any further
} else {
console.log('update successful - success add class to table row');
$this.closest('tr').addClass("success");
$this.closest('tr').removeClass("danger");
//$(this).closest('tr').attr('class','success');
}
}).fail(function(xhr) {
var httpStatus = (xhr.status);
var ajaxError = 'There was an error updating your selections - AJAX request error. HTTP Status: ' + httpStatus + '. Please contact Support';
console.log('ajaxError: ' + ajaxError);
$this.closest('tr').addClass("warning");
$('#alert_ajax_error').html(ajaxError);
$("#alert_ajax_error").show();
});
});
});
This is working when it comes to making the initial selection - the table row is coloured green to indicate it has been selected. I now need to extend this so that when the Select button is clicked a 2nd time it then removes the green table row highlighting and returns it to it's original state.
Now sure how to go about extending the script to achieve this.
Check below logic for that:
$('button.btn-success').click(function() {
if ($this.closest('tr').hasClass("first_click")) {
$this.closest('tr').removeClass();
//$( "tr" ).removeClass();
return false;
}else{
$this.closest('tr').addClass("first_click");
}
You chould achieve that by using a boolean to track the state of the button. Then check the state of the button before taking action.
Ps. You can chain your addClass() and removeClass() methods.
var buttonSelected = false;
if(buttonSelected){
$this.closest('tr').addClass("success").removeClass("danger");
buttonSelected = true;
} else {
$this.closest('tr').removeClass("success").addClass("danger");
buttonSelected = false;
}

AngularJs Click to toggle a image button src in a table

I'm binding a dynamic table in angularjs using following script:
$http.get('../Services/ReportServ.asmx/GetSelectedIndex', {
params: {InterviewId: InterviewId, EmpId: EmpId, ClientId: ClientId, Itype: '6'}
}).success(function (data) {
var myjson = JSON.parse(data);
$scope.ReportReviews = JSON.parse(myjson);
});
HTML:
<table id="tableReport" class="reportGrid">
<tr>
<th>
<input type="checkbox" ng-model="ReportReviews.allReviewed" ng-change="selectAllInivited()"/></th>
<th>Name</th>
<th ng-repeat="Header in Headers">{{Header.QUESTIONName}}
</th>
<th>OverAll</th>
</tr>
<tr ng-repeat="ReportReview in ReportReviews" ng-class="{selected: ReportReview.isReviewChecked}">
<td>
<input type="checkbox" ng-model="ReportReview.isReviewChecked" ng-change="selectInivited(ReportReview)"/>
</td>
<td>{{ReportReview.Name}}</td>
<td ng-repeat="Header in Headers">
<%--
<a runat="server" id="a1" ng-show="HideResult(interview)"
ng-class="{'checkedClass': (interview.R=='1' || interview.I=='1') , 'uncheckedClass': interview.I !='1'}">
<img class="imgResult" src="../Lib/img/Result.png" height="55px"/></a>
--%>
<input type="image" id="imgResult{{$index}}" ng-src="{{GetFolderPath(ReportReview,Header)}}" prevent-default
ng-click="imgResultClick(ReportReview,Header)" height="20px"/>
</td>
<td>
<input type="image" class="imgOverall" ng-src="{{GetOverallPath(ReportReview)}}" height="10px"/>
</td>
</tr>
</table>
I have used this script to bind imagebutton src. Now, I want to change the src of specific Image Button on click. I have tried the following method,
$scope.imgResultClick = function (fieldReport, fieldHeader) {
var id = event.target.id;
var imgPath = $('#' + id).attr('src');
$('#' + id).attr('src', ImgPath);
var output = imgPath.substr(0, imgPath.lastIndexOf('.')) || imgPath;
$('#' + id).attr('src', output + '_selected.png');
}
However, it has lot of issues. Example:
Can't reset the image path again on click back.
clicking on the same button agian will append the 'selected.png' string to the image path.
Can anyone guide me? Please let me know, if I need to provide further details.
Basically u should swap DOM-Manipulation into a Directive. In the directive you cna use the link Function to access the specific DOM-Element.But to solve your problem, you have just to use $scope.$apply it "forces" the manipulation
$scope.imgResultClick = function (fieldReport, fieldHeader) {
var id = event.target.id;
var imgPath = $('#' + id).attr('src');
$scope.$apply($('#' + id).attr('src', ImgPath));
var output = imgPath.substr(0, imgPath.lastIndexOf('.')) || imgPath;
$scope.$apply($('#' + id).attr('src', output+'_selected.png'));
}
If u want to toggle the Image, u have to set a flag and get the specific image. A tip u should work with directives' link function. Then u can get all the specific images. And handle them easily. A directive looks like:
app.directive('test', function() {
return {
restrict: 'AE',
link: function(scope, elem, attrs, event) {
elem.bind('click', function() {
//your logic to the image
var id = event.target.id;
var imgPath = $('#' + id).attr('src');
$scope.$apply($('#' + id).attr('src', ImgPath));
var output = imgPath.substr(0, imgPath.lastIndexOf('.')) || imgPath;
$scope.$apply($('#' + id).attr('src', output+'_selected.png'));
});
}}});

How can I improve performance of my javascript code

I have a page with a list of items. Items have several actions assigned to them. (see screenshot).
One may choose to directly click on an icon next to each row or check a checkbox on the left hand side.
The issue is that after clicking an item OR checking a checkbox of several items and then clicking an action there is a lag (a second or so). Imagine having 100 rows or more.
How can I improve the performance of my javascript code?
sample HTML of one row:
<tr id="1960AGIMMGMRTB20314" class="">
<td class="checkbox">
<input type="checkbox" value="1960" class="checkbox">
</td>
<td class="">
<p>GD009000246</p>
</td>
<td class="platform">PCGames</td>
<td class="cat">Up</td>
<td class="platform">
<div class="pbar"><span class="progresslabel"></span></div>
</td>
<td class="date">10.48.1.236</td>
<td class="options clearfix">
<a title="" class="iconMagnifier tip" href="/Packages/View/AGI-MM-GM-RTB-2.0.3.1.4">View</a>
<a title="" href="/Packages/PackageActionAsyncDeletePackage" data-ajax-type="DeletePackage" data-ajax-packageid="AGI-MM-GM-RTB-2.0.3.1.4" data-ajax-machineid="1960" class="iconDelete action tip">Remove</a>
</td>
</tr>
javascript:
// action invoker
$("a.action:not(.remove)").click(function (e) { // .remove => do not execute on download tasks page
var obj = $(this);
e.preventDefault();
if (!$(this).hasClass('disablelink')) {
var machineIds = getSelection(obj);
if (machineIds.length > 0) {
packageAction(obj.attr("data-ajax-packageid"), machineIds, obj.attr("data-ajax-type"));
};
}
$(".checkall").attr("checked", false);
});
function getSelection(obj) {
var selected = new Array();
if (obj.attr('data-ajax-machineId')) {
selected.push(obj.attr('data-ajax-machineId'));
} else {
$("input.checkbox:checkbox:checked:not(.checkall)").each(function () {
var machineId = $(this).val();
var packageId = obj.attr("data-ajax-packageid");
var operation = obj.attr("data-ajax-type");
if ($("#" + machineId + packageId.removeSpecialChars().toUpperCase() + "").size() != 0) {
var row = $("#" + machineId + packageId.removeSpecialChars().toUpperCase() + "");
row.has("a[data-ajax-type=" + operation + "]:not(.hide)").length ? selected.push(machineId) : $(this).attr('checked', false);
}
});
}
return selected;
}
// download, install, uninstall, remove, activate, deactivate package
function packageAction(packageId, machineIds, operationType) {
.....// to implement - not needed
Querying objects out of the DOM is slow. The best thing to do is hold all of your data in javascript objects, do all the calculations and stuff you want, THEN update the DOM all at once. Ember.js and some other javascript libraries/tools have bound data which is cool, meaning you change an attribute in the javascript object and it automatically updates the DOM!

Categories

Resources