I am developing MVC application.
I have a View in which I show the data row wise.
I have placed a remove link in that row, when user click on that link, that row should be remove.
But its not working...
I display the data in following format.
$('#ProductList').append("<div class='span12' style='margin-left:0px' ><div class='span2'>" +
"<select class='clsProductId ' name='ProductId' id='ddProductList_" + IDD + "' style = 'font-size:12px;width:200px;margin-right:80px;margin-left:20px;' onchange='get(" + IDD + ")'/> </div>" +
"<div id='ProductCode_" + IDD + "' class='span1' style=' margin-left:85px;'></div>" +
"<div id='Weight_" + IDD + "' class='span1' style=' margin-left:55px;'> </div>" +
"<div class='span1'style='margin-left:0px;'><input type='text' id='Quantity_" + IDD + "' class='clsQuantity' name='Quantities' style='width:50px; margin-left:0px;' onblur='StockLinkVisible(" + IDD + ");' /></div>" +
"<div class='span1' style='margin-left:0px;'><a href='#' style='font-size:14px;text-decoration:none;font-weight:bold; color :#ee8929; margin-left:20px;' id='lnkRemove_" + IDD + "' class='clsRemove' onclick='removeElement(" + IDD + ");'>X</a></div>" +
"<div class='span1'style='margin-left:10px; Width:60px;' id='Bandra_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:10px; Width:60px;' id='Dadar_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:0px; Width:60px;' id='Bhivandi_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:10px; Width:40px;' id='Juhu_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:10px; Width:40px;' id='Kurla_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:10px; Width:60px;' id='Dombivali_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:15px; Width:40px;' id='Worli_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:15px; Width:60px;' id='Sant_" + IDD + "'>123</div>" +
"<div class='span1'style='margin-left:0px; Width:40px;' id='Bandra_" + IDD + "'>123</div>" +
"<hr></div>");
for removing the row I have written the below code...
function removeElement(cnt)
{
$("#ProductList").on('click', '#lnkRemove_'+cnt, function () {
$(this).closest("div").remove();
});
}
Please check image below for better idea...
On the click event, you call a function
onclick='removeElement(" + IDD + ");
This function binds another click handler to itself, but doesn't actually do anything. Furthermore, the click handler will look for the closest div, which only wraps the delete button, and so doesn't quite do what you want.
$("#ProductList").on('click', '#lnkRemove_'+cnt, function () {
$(this).closest("div").remove();
});
Here's my suggestion: remove the onclick event and the function, and on document ready, register a generic click action as follows:
$('#ProductList').on('click', '.clsRemove', function() {
$(this).closest('div.span12').remove();
});
I chose the class span12 as the selector simply because it's the only one I saw that the top-level wrapping div (the "row") had. Feel free to add a more descriptive selector and using that instead.
You no need to call removeElement for each element. Just configure the below code in document.ready
$(document).ready(function(){
$("#ProductList").on('click', '.clsRemove', function () {
$(this).parents("div.span12:first").remove();
});
});
update to this:
function removeElement(cnt)
{
$('#lnkRemove_'+cnt).closest("div.span12").remove();
}
You don't need to bind click event again instead you can do as suggested or better to delegate the event to the closest static parent (try unobtrusive js):
$("#ProductList").on('click', '[id^="lnkRemove"]', function () {
$(this).closest("div.span12").remove();
});
Related
I have a parameter called foo. I use an API to send a call to an endpoint which, if successful, will then populate foo with the relevant payload data. foo has many properties, such as:
title
forename
surname
Abracadabra
What I want to do using jQuery is once all of these properties have been populated, I then want to go through them all and check if these properties are not populated or have a length equal to zero. If this is the case then I want to show a class of errorMesssage but only for that specific property.
This is the current code that I'm using to display my elements:
function createApplicationVerification1(customerData) {
var customerOne =
"<div class='row'><strong>Person 1:</strong></div><br />" +
"<div class='row validation-row'>" +
"<div class='col-md-6'><span>Title</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.p1Title) +
"</span></div>" +
"<div class='col-md-1'>" +
validateField(customerData.p1Title) +
"</div>" +
"</div>" +
"<div class='row validation-row'>" +
"<div class='col-md-6'><span>Forename</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.p1Forename) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.p1Forename) +
"</span></div>" +
"</div>" +
"<div class='row errorRow'><div class='col-md-6'> </div><div class='col-md-6 errorMessage'></div></div>" +
"<div class='row validation-row'>" +
"<div class='col-md-6'><span>Surname</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.p1Surname) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.p1Surname) +
"</span></div>" +
"</div>" +
"<div class='row validation-row'>" +
"<div class='col-md-6'><span>DOB</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.p1Dob.substring(0, 10)) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.p1Dob) +
"</span></div>" +
"</div>" +
"<div class = 'row validation-row'>" +
"<div class='col-md-6'><span>Address</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.app1Address) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.app1Address) +
"</span></div>" +
"</div>" +
"<div class = 'row validation-row'>" +
"<div class='col-md-6'><span>Town</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.app1Town) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.app1Town) +
"</span></div>" +
"</div>" +
"<div class = 'row validation-row'>" +
"<div class='col-md-6'><span>Postcode</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.app1Postcode) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.app1Postcode) +
"</span></div>" +
"</div>" +
"<div class = 'row validation-row'>" +
"<div class='col-md-6'><span>Country Code</span></div>" +
"<div class='col-md-5' id ='applicantInfo'><span>" +
checkIfEmpty(customerData.countryCode) +
"</span></div>" +
"<div class='col-md-1'><span>" +
validateField(customerData.countryCode) +
"</span></div>" +
"</div>";
return customerOne;
}
Once this data has been populated, I then call a checkForErrors() function which is this:
function checkForErrors() {
$(foo.childNodes).each(function () {
$(foo).filter(function () {
return $(foo, this).length == 0;
});
$(".errorMessage").text("Required Field.");
$(".errorMessage").css("display", true);
});
}
My thinking behind this is that for each foo.childNodes if it matches the filter where the length is equal to 0 then I want it to show the errorMessage.
With this I came across 2 issues.
childNodes brings up an error and breaks the js.
Because the class name is not unique, once I get one property that matches the rule of 0 in length, then it shows an error message for all properties.
The below image is a rough example of what i'm trying to achieve:
Here's what I'm currently getting:
I'm getting this because of the class for this html element is the same throughout.
How can I achieve the validation check in a better way than having to define each errorMessage's id?
You should structure your code according to standards.
Dont repeat. Create a function:
function createItem(title, value = "") {
var isValid = validateField(value); //not sure what you have in mind with that function but
//you should create dom elements https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
return "<div class='row validation-row'>" +
"<div class='col-md-6'><span>" + title + "</span></div>" +
"<div class='col-md-5' id ='applicantInfo'>" + value + "<span>" +
"<div class='col-md-1'><span>" +
(isValid ? "<span>Y</span>" : "<span>X</span>") +
"</span></div>" +
"<div>" + (value.length === 0 ? "" : "<span>Required Field.</span>") + "</div>" +
"</div>";
}
call that function with your data.
function createApplicationVerification1(customerData) {
var r = "<div class='row'><strong>Person 1:</strong></div><br />";
r += createItem('Title', customerData.p1Title);
r += createItem('Forename', customerData.p1Forename);
// ...
return r + "</div>";
}
You dont need a checkForErrors at all. Don't iterate over dom nodes just do it while you create your dom nodes.
I have an ajax post request for a form submit where i manipulate the page based on the values that are returned from the controller but my problem is that whenever the form is submitted i need to erase the values from the last request.For example, i submit the form and when that happens i add some text on the page if the form is submitted a second time i need to erase those values from the last time and add on the page new content.
Here is the code:
function ajaxPost(){
// DO POST
$.ajax({
type : "POST",
url : "/search",
dataType: "json",
data : {
'marcaId': $('#marcaId').val(),
'modelId': $('#modelId').val(),
'pretDeLa': $('#pretDeLa').val(),
'pretPanaLa': $('#pretPanaLa').val(),
'anFabrDeLa' : $('#anFabrDeLa').val(),
'anFabrPanaLa' : $('#anFabrPanaLa').val(),
'orasParam' : $('#orasParam').val()
},
success : function(data) {
console.log(data);
for(var i=0; i<data.length; i++){
$('.row.autovitElements').append("<div class='col-sm-3 elementAutovit'>" + "<div class='card' style='width:20rem;'>" +
"<img class='card-img-top' src=" + JSON.stringify(data[i].img) + "alt='Card image cap'>" +
"<div class='card-body text-center'>" +
"<p class='card-text text-center' style='color: black'>" +data[i].title+ "</p>" +
"<ul class='list-group list-group-flush'>" +
"<li class='list-group-item'>" +
"<div class='row'>" +
"<div class='col-md-6'>" +
"<i class='material-icons'></i><span>"+ data[i].price +"</span>" +
"</div>" +
"<div class='col-md-6'>" +
"<i class='material-icons'></i><span>"+data[i].city+"</span>" +
"</div>" +
"</div>" +
"</li>" +
"</ul>" +
"<button href=''#' class='btn btn-danger'>Save</button>" +
"</div>" +
"</div> " +
"</div> ");
}
})
I've tried with $('.row.autovitElements').hide(); but it won't work:(
for(var i=0; i<data.length; i++){
$('.row.autovitElements').append("<div class='col-sm-3 elementAutovit'>" + ...
The elements you are appending for the results of the ajax are elementAutovit, which are children of the .row.autovitElements element. So to "reset" the results, you would remove all those elements you appended, which could be done with:
$('.row.autovitElements .elementAutovit').remove()
Which would remove all those specific elements. OR, if there is nothing else in the container that you want to keep, you could simply empty it
$('.row.autovitElements').empty()
I used AJAX to dynamically create the HTML but I've encountered a problem
<script>
function page_loaded(){
jQuery.ajax({
method: "GET",
url: "get_data_dashboard.php",
success: function(data){
var markers = JSON.parse(data);
for(var i = 0; i < markers.length; i++){
var m = markers[i];
var markerHTML = "<div class='marker'>" +
"<span id='naziv'>Naziv zahtjeva: " + m.naziv + "</span></br>" +
"<span id='ulica'>Ulica: " + m.ulica + "</span></br>" +
"<p id='opis'>Opis:</br>" + m.opis + "</p></br>" +
"<span id='email'>Email: " + m.email + "</span></br>" +
"<img id='slika' src='" + m.link_slike + "' />" + "</br>" +
"<textarea rows='5' cols='30' maxlength='500' id='t" + m.marker_id + "' placeholder='Komentar'>" + "</textarea></br>"
+ "<div class='buttons'><a href='odobri_prijavu.php?id=" + m.marker_id + "'>Odobri</a>" +
"<a href='izbrisi_prijavu.php?id=" + m.marker_id + "'>Izbriši</a>" + "</div>" +
"</div><hr>";
$('#content').append(markerHTML);
}
}
})
}
$(document).ready(page_loaded());
</script>
I tried to use buttons first instead of anchor tags but I couldn't figure how to add event handlers to dynamically created buttons that will post a request via AJAX to some php script with the proper id as the value and the value of the textarea. So I used the anchor tag and I was able to send the id, but I can't send the value of the textarea because I don't know how to reference it and even if I referenced it, it will be NULL because its value is set to the anchor tag at the very beginning and I want to type in text in the textarea.
Instead of listening to individual "elements", you can actually listen to a parent of a specific element (You'll need to supply another parameter to on()). A popular pattern is to listen to "body" (because body is a parent to all, technically), but any non-dynamic parent element will work! Here's an example:
//notice the second parameter supplied
$("body").on("click", ".my-dynamic-element", function(e){
//awesome code that makes the world a better place goes here
//this code triggers when .my-dynamic-element is clicked, wootz
});
Event delegation is your friend.
I don`t see any actions that actually do event handling, but a simple solution would be something like:
$(document).on('click', '.your-button-class', function(){
// do your thing
});
<script>
function page_loaded(){
jQuery.ajax({
method: "GET",
url: "get_data_dashboard.php",
success: function(data){
var markers = JSON.parse(data);
for(var i = 0; i < markers.length; i++){
var m = markers[i];
var markerHTML = "<div class='marker'>" +
"<span id='naziv'>Naziv zahtjeva: " + m.naziv + "</span></br>" +
"<span id='ulica'>Ulica: " + m.ulica + "</span></br>" +
"<p id='opis'>Opis:</br>" + m.opis + "</p></br>" +
"<span id='email'>Email: " + m.email + "</span></br>" +
"<img id='slika' src='" + m.link_slike + "' />" + "</br>" +
"<textarea rows='5' cols='30' maxlength='500' id='t" + m.marker_id + "' placeholder='Komentar'>" + "</textarea></br>"
+ "<div class='buttons'>Odobri" +
"<a href='izbrisi_prijavu.php?id=" + m.marker_id + "'>Izbriši</a>" + "</div>" +
"</div><hr>";
$('#content').append(markerHTML);
}
}
})
}
$(document).ready(page_loaded());
function clickHandler(id){
$('#'+id) // selects the button
$('#t'+id) // selects the text area
}
</script>
I am trying to implement my own rich text editor using iframe. However, whenver I click inside the empty rich text editor, the caret or mouse cursor doesn't show up. After checking on google, I found that we need to add some html to the iframe beforehand such as 'break tag. But my code below will only add the break tag to the first rich text editor and not to the second. Not sure what I am doing wrong here.......
$.fn.createRichTextEditor = function(width,height="auto") {
var iframeDocument;
var iframeDocumentId = this.attr("id") + "-rte-editor";
var newHtml = "<div id='rte-" + iframeDocumentId + "' class='rte'>" +
"<ul class='rte-toolbar'>" +
"<li id='bold'><button id='rte-boldBtn-" + iframeDocumentId + "' class='rte-button' value='bold' title='Bold'></button></li>" +
"<li id='italic'><button id='rte-italicBtn-" + iframeDocumentId + "' class='rte-button' value='italic' title='Italic'></button></li>" +
"<li id='underline'><button id='rte-underlineBtn-" + iframeDocumentId + "' class='rte-button' value='underline' title='Underline'></button></li>" +
"<li id='createLink'><button id='rte-createLinkBtn-" + iframeDocumentId + "' class='rte-button-link' value='createLink' title='Link'></button></li>" +
"<li id='unlink'><button id='rte-unlinkBtn-" + iframeDocumentId + "' class='rte-button-link' value='unlink' title='Unlink'></button></li>" +
"</ul>" +
"<iframe class='rte-iframe' id='" + iframeDocumentId + "' frameBorder='0'></iframe>" +
"</div>";
this.after(newHtml);
this.css('display', 'none');
var iframe = document.getElementById(iframeDocumentId);
var rte = iframe.parentElement;
$(rte).css('width', width);
$(rte).css('border', '1px solid #ccc');
$(iframe).on('load', function() {
$(iframe).width("100%");
$(iframe).height(height);
iframeDocument = iframe.contentDocument;
iframeDocument.designMode = 'On';
$(iframeDocument).find('body').html('<br><br/>');
});
};
You need to loop through each matching element in your plugin:
$.fn.createRichTextEditor = function (width, height) {
this.each(function () {
// Your code for each element here
});
});
I'm iterating with
function editRow(a) {
$("td").each(function () {
alert($(this).val())
});
}
which iterates through
$("tbody").append(
"<tr id = '" + trId + "'>" +
"<td name = 'nameRow' id = 'name" + idCt + "' value = 'test' > <strong>" + name + "</strong> </td>" +
"<td name = 'maxRow' id = 'max" + idCt + "' value = '" + max + "'>" + max + "</td>" +
"<td name = 'setRow' id = 'sets" + idCt + "' value = '" + sets + "'>" + sets + "</td>" +
"<td name = 'repRow' id = 'reps" + idCt + "' value = '" + reps + "'>" + reps + "</td>" +
"<td name = 'restRow' id = 'rest" + idCt + "' value = '" + rest + "'>" + rest + "</td>" +
"<td id = 'link" + idCt + "'><a href='#' onclick='return deleteRow(" + trId + ");' >Remove</a>" +
" | <a href='#' onclick='return editRow(" + idCt + ");'>Edit</a></td>" +
"</tr>"
);
The alter($(this).val()) is coming up the correct amount of times, but it is always just blank (not undefined)).
I know it's not that readable, but does anyone see an error?
Thanks!
.val() is a method which is only defined for input elements. Normal HTML elements don't have a value. You should use .html() or .text() to get the content of those elements
function editRow(a) {
$("td").each(function () {
alert($(this).text())
});
}
You should define non-standard attributes (like value for <td>) using the data- prefix
<td data-value="whatever">...</td>
Then you can use jQuery's .data() method to access those attributes
var tdDataValue = $(this).data('value');
The problem is that "td" - elements haven't values. They have inner HMTL. If you want to get td's content, you need to use $(this).html()
function editRow(a) {
$("td").each(function () {
alert($(this).html())
});
}
The val method is usually reserved for input tags. For td you can do either:
$(this).text();
or
$(this).attr('value');
simply try something like this
function editRow(a) {
$("td").each(function () {
alert(this.innerText);// reading inner text
alert($(this).attr('value'));// reading value attribute
});
}