jQuery: Detect duplicate in select & show an alert - javascript

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/

Related

Adding a details button to a dynamic HTML list

I have an HTML list that is generated dynamically using filtered data.
<tbody>
#{
foreach (var item in listado.Where(x => x.Raw != null)) {
<tr>
<td>#item.Id</td>
<td>#item.Usuario</td>
<td>#item.NIF_CIF</td>
<td>
#if (!(String.IsNullOrEmpty(item.Telefono)) && !(String.IsNullOrWhiteSpace(item.Telefono))) {
#item.Telefono
} else {
#Html.Raw("No disponible")}
</td>
<td>#Math.Round(item.PrecioTotal) €</td>
<td>#item.FechaCreacion.ToShortDateString()</td>
<td>
<button id="detalles#(item.Id)">Detalles</button>
</td>
</tr>
<tr id="vistaDetalles#(item.Id)" hidden>
<td>Detalles del presupuesto</td>
</tr>
}
}
</tbody>
I've tried to tag the button as you can see using the item.Id and then point to it in this script:
<script>
$("document").ready(function (Id) {
$("#detalles"+ Id).click(function (Id) {
$("#vistaDetalles" + Id).show();
});
});</script>
I've also tried not to tag them and catch all the buttons (removing the +Id part) and the same technique to catch all the hidden tds, but nothing works. What am I doing wrong? Also, can you recommend some learning material so I can get this part a bit clearer?
Thanks in advance. Regards.
You can use data attributes for this purpose
HTML
<button class="detalles" data-itemid="#item.Id">Detalles</button>
jQuery
$(".detalles").on("click",function(){
var itemId = $(this).data('itemid');
$('#vistaDetalles'+itemId).show();
});
I would replace your button with
<button onclick="detalles(#item.Id)">Detalles</button>
And change your JavaScript to:
<script>
function detalles(Id) {
$("#vistaDetalles" + Id).show();
};
</script>
Try it:-
<script>
$("document").ready(function (Id) {
$("body").on("click","#detalles"+ Id, function (Id) {
$("#vistaDetalles" + Id).show();
});
});</script>

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;
}

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!

jquery removing string parts from two areas

I'm looking to expand on a recent script i've coded using jquery.
I have this following code
<script type='text/javascript'>
added_departments = new Array();
$("#departments_submit").click(function(){
var depo = $("#depo_list").val();
if(jQuery.inArray(depo, added_departments) != -1)
{
return false;
}
else
{
added_departments.push(depo);
$("#depo_added_list").append("<li>" + depo + "<a href='#' title='"+ depo +"' class='remove_depo'> [X] </a></li>");
var current_value = $("#departments").val();
if(current_value)
{
$("#departments").val(current_value + "," + depo);
}
else
{
$("#departments").val(depo);
}
return false;
}
});
</script>
The above code takes information selected in a select drop down box, adds it to a div to display publicly and also into a hidden form field that processes the data.
i've tried to create now something that will reverse this effect and remove certain selections from the div and the field. which is where i have this code
<script type='text/javascript'>
$(".remove_depo").click(function(){
var removing = $(this).title();
var current_val = $("#deparments").val();
if(current_val == removing) {
$("departments").replace(removing, "");
}
else {
$("departments").replace("," + removing, "");
}
});
</script>
It doesn't cause any errors, but it doesn't do anything either? So I'm really stuck. Any ideas?
EDIT: Updated code
$(".remove_depo").click(function(){
var removing = $(this).attr('title');
var current_val = $("#deparments").val();
if(current_val == removing) {
$("#departments").replace(removing, "");
}
else {
$("#departments").replace("," + removing, "");
}
});
Here is the html
<form method="post" action="javascript:void(0);">Select Departments To Be Added:
<div class="depo_adder">
<select id="depo_list"><option value="">--- INDIVIDUAL TAGS ---</option><option value="blah">blah</option></select>
<button id="departments_submit">Go!</button>
</div></form><form method="post" action="briefings/addbriefing.php">
<div class="form">
<strong>Departments: </strong>
<ul id="depo_added_list"><li>blah [X] </li></ul>
<input name="departments" id="departments" value="blah" type="hidden">
</div>
you're referring to $('departments') - this won't work. You need to specify either an identifierm eg $('#departments') or a class, eg $('.departments)
ah - other answer is also correct, .title() is not a function. You want
$('#foo').attr('title') to get the title.

Categories

Resources