add element containing ng-if using jquery after - javascript

I am trying to add some validation to some input using a directive. I'm using the following code to add the validation alert but the ng-if doesn't seem to be registering and the messages are constantly displayed.
if (addMessages) {
angular.element(element).after('<div><span ng-if="form.' + scope.fieldName + '.$error.maxlength">Please keep it under ' + property.length + ' characters.</span></div>' +
'<div><span ng-if="form.' + scope.fieldName + '.$error.required">This field is required</span></div>')
element.removeAttr("my-directive");
$compile(element)(scope);
}
I originally tried to do this with ngMessages but they are not currently working on mdDialogs where most of my input is contained, so I came up with this solution, but its just not working for me. Any ideas?

In your code when you execute $compile(element)(scope); it is actually compiling the element which do not contain the html you just added in the previous line. It is because element.after adds the html after the element. So you have to get a reference to the dynamic element inserted and then call $compile on it, it should work fine.
if (addMessages) {
var $htmlToInsert = $('<div><span ng-if="form.' + scope.fieldName + '.$error.maxlength">Please keep it under ' + property.length + ' characters.</span></div>' +
'<div><span ng-if="form.' + scope.fieldName + '.$error.required">This field is required</span></div>');
angular.element(element).after($htmlToInsert)
element.removeAttr("my-directive");
$compile($htmlToInsert)(scope);
}
Demo http://plnkr.co/edit/Vjt1PTGfbLa6zA0iRYSz?p=preview

Related

When I .load a HTML template, JSON elements don't populate but they work fine as static HTML.

I don't think this is a broken code question as much as it is a question about understanding JS.
I have HTML templates that I load when an element is clicked. To be clear, there is already an HTML template loaded on document.ready that has all functionality working just fine. The HTML that loads is the exact HTML that is in place when you intitially load the page, aside from some small differences(images, etc...). This all loads no problem, but for some reason my JSON elements don't load. Is this because the actual javascript I wrote that is responsible for loading the JSON is within the document.ready wrap?
To be clear, the HTML is EXACTLY the same, aside from text and img src's. I have provided the JS though since that may be the issue.
Just looking for some guidance on why this may be occurring since I also have a few other JS/jquery strings of code that also don't work on template load(like hiding elements with .hide that work on document.ready no problem, but once the template loads, the elements aren't hiding).
This all sits in $(document).ready
var trinketJSON;
$.getJSON("js/trinket.json", function (data) {
trinketJSON = data;
// TRINKET SELECTION TABLE
$.each(trinketJSON, function (i, item) {
$("<div>")
.html(
'<div class="trinket-tile"><div class="trinket-img" style=\'background-image: url("' +
trinketJSON[i].RarityBG +
'");\'><img src="' +
trinketJSON[i].TrinketIMG +
'" class="trinket-tile-img"></div><div class="trinket-effects"><ul><li class="trinket-effect">' +
trinketJSON[i].EffectOne +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectTwo +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectThree +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectFour +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectFive +
'</li><li class="trinket-effect">' +
trinketJSON[i].EffectSix +
'</li></ul></div><div class="trinket-info"><ul><li class="trinket-name">' +
trinketJSON[i].TrinketName +
'</li><li class="trinket-rarity">' +
trinketJSON[i].Rarity +
'</li><li class="trinket-class">' +
trinketJSON[i].Class +
'</li><li class="trinket-set"></ul></div></div>'
)
.appendTo(".trinket-select");
});

How to add an ID value to a div append

I have a "fault-counter" that stores a value of all incorrect answers. It starts at 0 and goes up one for every wrong answer.
I'm looking to have the results screen show the amount of faults you've made. So if the div #fault-counter has a value of 3, the end text will say "Sorry, you've made 3 faults!"
This is the code I've tried, but it doesn't seem to work. Any ideas on how to do this?
var faultcounter = $('#fault-counter');
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter') + ' faults!</h1>');
EDIT:
The HTML for the 'fault-counter' looks like this:
<div id="fault-display">
<div id="fault-counter">0</div>
<h3>FAULTS</h3>
</div>
And the jQuery being used to increase the value for every wrong answer is this:
$(".failQuestion").click(function(){
$('#fault-counter').html(function(i, val) { return val*1+1 });
});
Try this, as your fault-counter is a div than .text() should suffice.
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').text() + ' faults!</h1>');
var faultcounter = $('#fault-counter').val();
$('#slickQuiz').prepend('<h1>Sorry, you have ' + faultcounter + ' faults!</h1>');
You'll have to grab the value from #fault-counter using .val() and then append the variable, instead of the jQuery selector to the #slickQuiz.
That being said, i'm assuming you're using an input or select for #fault-counter. Otherwise .text() would be sufficient
i think there is a problem :
var faultcounter = $('#fault-counter');
if $('#fault-counter') is a input control then use "VAL()" :
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').val() + ' faults!</h1>');
OR
if $('#fault-counter') is a DIV control then use "html()" :
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').html() + ' faults!</h1>');
var faultcounter = $('#fault-counter').text();
$('#slickQuiz').prepend('<h1>Sorry, you have ' + faultcounter + ' faults!</h1>');
This is what you want to use because you mentioned that #fault-counter is a div. If that's so then you'll want to use the .text method. If it's an input or textarea then use the .val method.

angular ng-click event not firing

I have a function that adds certain html to my page when called :
function htmlAppend(i)
{
dynamicHtml = dynamicHtml + '<div id="list_item_wrapper">' +
'<div class="list_item_template" id="list_image_wrapper">' +
'<img class="list_image_style" ' +
'src=" ' + jsonData.cars[i].ImgURL + ' "/>' +
'</div>' +
'<div class="list_item_template white_font car_details_wrapper">' +
jsonData.cars[i].CarName+ '<br>' +
jsonData.cars[i].Brand + '<br>' +
jsonData.cars[i].Model + '<br>' +
jsonData.cars[i].FuelType + '<br>' +
'<span style="font-size:40px;">' +
'₹ ' + jsonData.cars[i].Price +
'</span> <br> ' +
jsonData.cars[i].Experience +
'<input type="button" id="buy_now_btn" class="button1" ng-click="alert("hi")">Buy</button>' +
'</div>' +
'</div>'
}
Problem : Now this html is displayed correctly in my page but for some reason when button is clicked ng-click event doesn't fire , when i replaced it with onClick then onClick fires . i am unable to understand why ng-click is not firing , can somebody help ?
Additional Info : htmlAppend is a private function of a service that is called from the controller upon some user input.
No, you can't just write alert on your ng-click. When you write alert("hi") on your ng-click directive, it automatically goes and look for a method in your controller that is named $scope.alert(). That is why onClick works, because it is just plain old JavaScript, where as ng-click involves scope binding.
In your controller, write this:
$scope.alert=function(string){
alert(string);
};
and you are good to go. Here is the working plnkr.
Edit: did not read carefully that you are dynamically binding it. Updated plnkr.
For this case you will need to compile it:
var $el = $('<button ng-click=' + 'alert("hello")' + '>I am a button</button>');
$compile($el)($scope).appendTo('#testing');
where #testing can be any DOM selector you want.
Still the point is to tell you you can't just write alert in ng-click directive.
Added bonus: do not write DOM manipulating logic inside the controller. You may want to use a directive instead.

Put a Modal inside Javascript

I'm making a Carnival calendar for my city.
I'm using this as a basic calendar engine: https://github.com/jlord/sheetsee-calendar
For a basic Modal i'm using this: https://github.com/FinelySliced/leanModal.js
I want to be able to click on the event and put it to show some information about it: name, time and place.
var eventElement = $('<div class="event"><a class="' +
event.location + '" href="#informa" rel="leanModal" >' +
event.name + "#" + event.tickets +
'</a></div> <div id="informa"> <p>' +
event.name + '</p></div>')
I made a test modal in the index.html and it worked, but it is not working when i try to do this.
You have created an element, but haven't added it to the DOM of the page.
try something like
$('body').append(eventElement);
as the next line.

using .append to build a complex menu

To build a menu block which should be switchable with hide/unhide of the menu items, I'm using .append html.
The code idea is this:
navigat += '<h3 class="infoH3"> <a id="' + menuID +'"'
+ ' href="javascript:slideMenu(\'' + menuSlider + '\');">'
+ menuName + '</a></h3>';
navigat += '<div id="' + menuSlider + '" style="display:none">';
navigat += ' <ul>';
navigat += ' <li>aMenu1</li>'
navigat += ' <li>aMenu2</li>'
navigat += ' <li>aMenu3</li>'
navigat += ' </ul>';
navigat += '<!-- menuName Slider --></div>';
$("#someElement").append (navigat);
This is doing well .. so far.
But the point is::
I use JS to read the required menu items (eg. 'aMenu1' together with title and/or link info) from a file to build all that, eg. for 'aMenu1' a complex is composed and $("#someElement").append(someString) is used to add that the 'someElement'.
At the moment I build those html elements line by line. Also OK .. as far as the resulting string has the opening and closing tag, eg. "<li>aMenu2</li>".
As can be seen from above posted code there is a line "<div id="' + menuSlider + '" style="display:none">".
Appending that -- AFAIS -- the .append is automatically (????) adding "</div>" which closes the statement.
That breaks my idea of the whole concept! The menu part isn't included in the 'menuSlider '.
QQ: How to change it -- NOT to have that "</div" added to it??
Günter
You could change you method around to use document fragment style creation and an object to populate the properties on the elements, like this:
var someElement = $("#someElement");
$('<h3 class="infoH3"></h3>').append($('<a />',
{ 'id': menuID,
'href': '#',
click: function() { slideMenu(menuSlider); }
})
).appendTo(someElement);
var div = $('<div />', { 'id': menuSlider, css: {display: 'none'} });
$('<ul />').append('<li>aMenu1</li>')
.append('<li>aMenu2</li>')
.append('<li>aMenu3</li>')
.appendTo(div);
div.appendTo(someElement);
This is a very different way of doing it, first we're caching the $("#someElement") object so we're not searching for it repeatedly. Then we're creating the <h3> as an object, putting the link inside, then inserting then appending the whole thing to someElement. In the last, the same approach it's creating the <div>, setting it's properties, then creates the <ul> menu and appends it inside...then appends that whole div to someElement as well.
As a side note, I'm not sure how .slideMenu() works, but an event handler that works via $(this).parent().next() (or give the div a class) would work as well, and you wouldn't need a function with the slider argument passed.

Categories

Resources