Delete AngularUI Accordion on ng-repeat - javascript

So I'm trying to add a delete function to my ng-repeating accordion.
The button is displayed and the function is set up, but when the delete button is pressed the page reloads almost and then redirects to localhost:8080/# however it should not redirect to here, and there is nothing suggesting it should redirect to here, not that I can see anyway, maybe this is one of the problems? However I'm unable to see were this would originate from..
As the application isn't hosted yet once the page is refreshed, all of the data is lost, as it is passed to the current editing view, by the view before it, which displays them in a table until you click on one of the rows and get taken to said editing page.
Here is my JS delete function:
$scope.delete = function (index, event) {
if(event) {
event.preventDefault();
event.stopPropagation();
}
$scope.selectedTestScript.Actions.splice(index, 1);
}
And here is my ng-repeat accordion:
<uib-accordion close-others="oneAtATime">
<uib-accordion-group ng-repeat="action in selectedTestScript.Actions" is-open="action.isOpen" ng-click="action.isOpen=!action.isOpen">
<uib-accordion-heading>
<div>{{action.Description}}<button type="button" class="btn btn-xs btn-danger pull-right" ng-click="delete($index, event)"></i>Delete</button></div>
</uib-accordion-heading>
<div>
<label for="actionNotes" class="control-label col-xs-2">Action Notes</label>
<div class="col-xs-10">
<textarea id="actionNotes" type="text" rows="4"ng-model="action.Notes" class="form-control" name="name"></textarea>
</div>
</div>
<div>
<label for="actionExpected" class="control-label col-xs-2">Action Expected</label>
<div class="col-xs-10">
<input id="actionExpected" type="text" ng-model="action.ExpectedOutcome" class="form-control" name="name">
</div>
</div>
</uib-accordion-group>
</uib-accordion>
Any help would be much appreciated, I've tried simplifying the function and removing the if(event) statement and leaving it as a splice, but this also doesn't work.
Thanks in advance.

I guess you have a form surrounding the code you posted?
If that is the case, using <button> with no type specified defaults it to type=submit, which triggers the original HTML form submit, thus the redirect.
You can set type to button to prevent that from happening.
Also action.isOpen==!action.isOpen doesn't look correct, do you mean single =?
Edit: There is actually a paragraph under ui-bootstrap accordion that reads
Known issues
To use clickable elements within the accordion, you have to override
the accordion-group template to use div elements instead of anchor
elements, and add cursor: pointer in your CSS. This is due to browsers
interpreting anchor elements as the target of any click event, which
triggers routing when certain elements such as buttons are nested
inside the anchor element.
http://angular-ui.github.io/bootstrap/#/accordion

Related

Several radio button groups in nested ng-repeat, but only last group shows the value

I have a page where I want to update a form with several radio buttons. I query an api, and use the returned array of objects to populate the current values for the radio buttons. The problem that I have is that only the last set of radio buttons actually shows the value. This is the code that I have (I am using [[ and ]] for the start and end symbols for angular):
<fieldset data-ng-repeat="s in sections">
<div class="form-group">
<div class="col-md-12">
<h2>[[ s.section.name ]]</h2>
</div>
</div>
<!-- Field Item -->
<div class="form-group m-b-20 bg-light" data-ng-repeat="f in s.fields">
<div class="col-md-12 m-b-30">
<h4>[[ f.field.name ]]</h2>
<input type="text" data-ng-model="f.comments" class="form-control input-md underline" placeholder="Comments">
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="pass" class="form-control" data-ng-model="f.field_condition">
<label class="eval-pass"><i class="fa fa-check-circle green"></i> Pass</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="fail" class="form-control" data-ng-model="f.field_condition">
<label class="eval-fail"> <i class="fa fa-exclamation-circle red"></i> Fail</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="n/a" class="form-control" data-ng-model="f.field_condition">
<label class="eval-na"> <i class="fa fa-circle blue"></i> N/A</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="caution" class="form-control" data-ng-model="f.field_condition">
<label class="eval-caution"><i class="fa fa-exclamation-triangle yellow"></i> Caution</label>
</div>
</div>
[[ f.field_condition ]]
<hr>
</fieldset>
So basically, I have several sections, and each section has several fields. Each field has it's own radio button group (I am using the section and field ids to name the radio group). What I currently see is only the last field in each section actually shows the selected radio button. The other fields don't have any selection, even though the value for ng-model definitely does (I am showing the value of f.field_condition just to make sure there is a value).
For each field, I can see that the model is set. And if I select a value manually, I can see that the model changes, so it seems to me that the model is setup correctly. I just don't know why it won't initially show as selected for all rows but the last one.
I should also mention that if I save the form even with the missing radio button selections, the database is updated properly (it doesn't set the values to null, and if I manually change the selected value, it is updated in the db as well).
Does anyone have any ideas? Thanks!
EDIT
Here is a fiddle for this, although, it is working as expected in the fiddle. http://jsfiddle.net/dq8r196v/367/
I tried using the static data that I used in the fiddle, but I am still having the same problem. Does anyone know if this could be a CSS problem? The radio buttons are styled, and I didn't write the HTML or CSS.
UPDATE
I am still having this issue, so I built a new angular app and only used the code that is included in the fiddle that I have created. I am having the same problem with this new app, even though the same code works in the fiddle. I really don't understand what's happening here, but if anyone could shed some light, I would really appreciate it.
I have literally copied and pasted the code from my fiddle into a new angular app, and only the last group of radio buttons in each section is showing the value in the app.
Here is my complete code for the new angular app if someone else wants to try it out and see exactly what is happening: https://pastebin.com/qSR33yfM
I created the app on a single page for simplicity.
Here is the link to a pastebin with the exact json that I am using in my app: https://pastebin.com/utfVVQfT
I fixed the problem you're having by simply adding an array of objects ($scope.values) representing the different radio button options, and using an ng-repeat to create your radio buttons. See the following for the updated code: https://pastebin.com/s3hNzaXX
I know there are semantics around ng-repeat creating new $scopes, and imagine there is a conflict in scopes with your nested ng-repeats where it's binding to the radio buttons incorrectly and at a scope different than you want (the section level ng-repeat).
To confirm this suspicion, you could convert all of your interpolations in the code to use functions and console.log s and f at different points and confirm that field_condition is being set at a level you didn't intend.
Either way, it' best practice to create your radio buttons through data (and using ng-repeat), as is done with the $scope.values array, and a good side effect to doing this is not only can you update the different value options using data through AJAX or however you would like, but you won't have weird angular scoping issues as you're experiencing in your current code above.

GTM Event on Content

I can't see to find an answer to this one anywhere. I'm trying to setup a trigger and event tag in Google Tag Manager to fire whenever content is present. Essentially, I am creating a simple event in Google Analytics for Product Views. The developer for this site is expensive, so I'd like to handle it purely in GTM.
One piece of content that only exists on product pages is the submit on the cart button.
Can anyone recommend a method to inject some code with GTM to fire when content exists so I can trigger a tag off it?
Here is the html in and around the cart button. I'm thinking that I can fire something when class="clsAddCartRight" exists or the submit - either one:
<div id="variationGroup" class="clsViewItemVariationGroup clsOverflow" style="clear:both;">
<div class="clsViewItemVariationList clsOverflow" style="width:200px;margin:0 auto;">
<select name="item_variations" id="item_variations_496" onchange="getDetails()">
<option value="1606" selected="selected">Medium</option>
<option value="1607">Large</option>
</select>
</div>
<div class="clsItemSaleDetailBlockBottom">
<form name="purchaseItemFrm" id="purchaseItemFrm" action="http://www.runwaycrush.com/marketplace/cart.html" method="post">
<input type="hidden" name="item_id" id="item_id" value="1602">
<input type="hidden" name="c_action" id="c_action" value="add">
<input type="hidden" name="item_ref" id="item_ref" value="kanduclothing">
<input type="hidden" name="item_matrix_id" id="item_matrix_id" value="4721">
<div class="clsItemCartBlock clsFloatRight" id="addCartButton" style="margin:20px auto 0px; width:318px;">
<div class="clsAddCartLeft">
<div class="clsAddCartRight">
<input type="submit" name="add_to_cart" id="add_to_cart" value="ADD TO CART">
</div>
</div>
</div>
</form>
</div>
</div>
You can use a DOM type variable in GTM and use the "CSS Selector" option to select the element by classname (if the same class is there multiple times it will pick the first occurence). If you set the attribute name field to "class" the value for that variable will be the value of the class attribute.
Actually I think it would be better if you use the button itself and look for the "id" attribute with the value of "add_to_cart", because ids are unique per page (or should be).
However you also need an event to trigger a tag.
The value will be available only after the DOM has rendered. So the easiest way would be to set up a pageview and set the trigger type to "DOM Ready" and have if only fire when the value of your DOM variable matches the classname (or id respectively) of the button.
However if your product page urls follow any recognizable pattern it would be a lot better to use a url filter in a pageview trigger. That way you could have your tags trigger on pageload, which for many tags is much preferable.

Keeping AngularJS controls states on back button

I have a button group that acts like a radio button group like the following:
<div class="col-md-10" data-ng-controller="type-controller">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'1'">
Option 1
</label>
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'2'">
Option 2
</label>
</div>
<input data-ng-model="typeId" name="typeId" type="hidden" ng-init="typeId = '1'" />
</div>
When I submit the form, the selected "radio" goes to the input hidden and it works as expected. The problem is if the user uses the back button. Let's say the user is on the page containing the code above, then the page navigates to another one, then if the user clicks the back button, the "state" of the button group is not kept. It resets making the UX not cool.
So how do I keep the value if the user leaves the page and comes back using the back button? I had this same problem in a different project that I could easily fix by triggering the functions that handle the "change" event using jQuery. I would just check the value of the hidden and set the control state accordingly. But now I'm not using jQuery anymore and I don't think I should manipulate the DOM from within my controller.
I'm using Angular and this site is not a SPA, using ajax to get the values is not the case here.

jquery .focus(func) doing process several times

EDIT:
Thanks to Puneet who created this fiddle: http://jsfiddle.net/G3vSK/
It seems that it doesn't work on Chrome Version 28
On Firefox (v22) the alert comes once, but you can't enter anything in the boxes
Another problem I can't solve:
This is my Javsacript-Code:
function updateFieldsetStyleAdjustment(){
alert("update");
$('fieldset').not('[data-style=\'none\']').find('input, select, textarea, button') //find input-fields
.focus(function(){
alert("active: "+$(this).attr('id'));
});
}
This function should add an onfocus-Handler to some input-fields on my site.
Whenever I focus an field to insert a value, it should be called.
My problem is that, when I focus an input-field, the function is called several times. The number of calls/alerts varies from 3 to 16 or more per focus-Event.
However, my field never looses focus.
I apply the onfocus-event 2 times (The "update"-alert appears twice), but this is normal.
(I don't add 16 onfocus-event listeners to the input-fields).
Anyone knows what I'm doing wrong?
EDIT:
Here's the HTML-snipped:
<fieldset id="fs_1" data-style="data" d class="">
<legend>General Information</legend>
<div class="lineWrapper inputTooltip" data-tooltippos="left">
<label for="fs_1_form51f37d255fb35_name">Name</label>
<span class="inputWrapper">
<input type="text" id="fs_1_form51f37d255fb35_name" name="name" autofocus="" maxlength="40" tabindex="50">
</span>
</div>
<div class="lineWrapper inputTooltip" data-tooltippos="left">
<label for="fs_1_form51f37d255fb35_ansprechperson">Ansprechperson</label>
<span class="inputWrapper">
<input type="text" id="fs_1_form51f37d255fb35_ansprechperson" name="ansprechperson" maxlength="40" tabindex="51">
</span>
</div>
<!-- ...more Wrappers with input-fields... -->
</fieldset>
<!-- ...more fieldsets... -->
How I call it:
1.) $(document).ready(function() { updateFieldsetStyleAdjustment(); });
2.) After every Ajax-Request I call it again (the input-fields are loaded via Ajax)
unbind:
When I put $(this).unbind('focus'); inside my focus-eventhandler, it is triggered only once. But when I focus the same field again, it doesn't work anymore (as expected).
When I put $('*').unbind('focus'); on the beginning of my updateFieldsetStyleAdjustment()-Function, it doesn't change anything.
The alert() was the bug.
Realised that everything was working fine without the alert(). And the event was also only triggered once.
The alert always unfocused the input-field, and so a new alert was created.
I hate it, when my debugging-code is the only bug in the program.
I think your problem lies here.
After every Ajax-Request I call it again (the input-fields are loaded via Ajax).
Try binding focus with only the new fieldset generated after ajax calls (try using jQuery.on() function). Alternatively try
$('fieldset').not('[data-style=\'none\']').find('input, select, textarea, button').unbind('focus');
//unbind focus from previously binded dom elements.
and then call
updateFieldsetStyleAdjustment

Prepend object using jquery and disappear

I am writing a javascript file using jquery in order to inject the input box on the html page. However, when I inject the input on the page and within a few second the input box disappear. I am wondering why is that happen.
function injectArea(data) {
$('#test').prepend('<input type="text" class="input-block-level" placeholder=" " value="hi">');
}
P.S. I m using twitter bootstrap. not sure if that causes the problem.
when i call the function i do this:
$(document).ready(function(){
$(#button).click(injectArea);
});
This is my html:
<form class="form">
<button id ="button" class="btn btn-large btn-primary">Update Profile</button>
</form>
This fiddle shows that there is nothing wrong with prepend or the way you are using it. The issue must come from elsewhere. My guess is that you may have an AJAX callback that fires a few seconds after you call it which is overriding the change you are making to #test.
Fiddle:
http://jsfiddle.net/jy43A/
Update:
You said:
For some reason my page refresh itself.
#button is a <button> tag. Clicking on it will submit the form and refresh the page (if it targets the current page). use preventDefault(); to stop the submit default action:
function injectArea(data) {
data.preventDefault();
$('#test').prepend('<input type="text" class="input-block-level" placeholder=" " value="hi">');
}
You can see that the text box appears, then the page refreshes. This will look different in your case, but it will probably be along the same lines as this:
The effect WITHOUT preventDefault():
http://jsfiddle.net/jy43A/3/
And this works:
The effect WITH preventDefault():
http://jsfiddle.net/jy43A/2/
More info:
preventDefault info:
http://api.jquery.com/event.preventDefault/
Are you sure you're using the right method?
prepend:
<div id="a"></div>
$("#a").prepend("<span>");
<div id="a">
<span></span>
</div>
insertBefore:
<div id="a"></div>
$("#a").insertBefore("<span>");
<span></span>
<div id="a"></div>

Categories