Get the value of an input scope with angular ng-switch - javascript

What it should do
Each button is linked to a div block (ex: button01 links to block01). Each div block has 3 inputs. The last input gets the value of the a math function between the two inputs above it. The div blocks must "appear" not show/hide.
What it does
The part where the three buttons open the three div blocks works. The problem is that when I try to type something inside the two inputs the last input gets nothing.
What I've tried
1) ng-switch and ng-switch-when
2) place the divs inside each (script type="text/ng-template" id="aaa")
and then;
var forms = ["aaa", "bbb", "ccc", "ddd"];
credit_block.displayedForms = [];
credit_block.addForm = function(formIndex) {
credit_block.displayedForms = [];
credit_block.displayedForms.push(forms[formIndex]);
}
3) (this one worked but it's not what I want) ng-show
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div class="row">
<div class="col-sm-12">
Pick a topic:
<label><span>Button01</span><input style="display:none" type="radio" ng-model="myVar" value="block01"></label>
<label><span>Button02</span><input style="display:none" type="radio" ng-model="myVar" value="block02"></label>
<label><span>Button03</span><input style="display:none" type="radio" ng-model="myVar" value="block03"></label>
</div>
</div>
<div class="row" ng-switch="myVar">
<div class="col-sm-12" ng-switch-when="block01">
<h3>Cumpar locuinta</h3>
<div class="row">
<div class="col-sm-10 col-xs-8 number-box">
<label>Sum:</label>
<input class="button-option" type="number" ng-model="sum">
</div>
</div>
<div class="row">
<div class="col-sm-10 col-xs-8 number-box">
<label>Advancement:</label>
<input class="button-option" type="number" ng-model="adv">
</div>
</div>
<div class="row">
<div class="col-sm-10 col-xs-8 number-box">
<label>Value:</label>
<input class="button-option" type="number" value="{{ result() }}">
</div>
</div>
</div>
</div>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope) {
$scope.sum = 5;
$scope.adv = 4;
$scope.result = function() {
return $scope.sum - $scope.adv;
};
});
</script>

You've got a classic scope-related variable shadowing problem.
ng-switch creates a new scope, so your ng-model bindings to sum and adv don't correspond to the ones you've set up in myController.
A usual way to work around this newly created scope is to put ng-model properties for binding behind an object and reference them through it.
For example, in your HTML:
<input class="button-option" type="number" ng-model="data.sum">
Then in your controller:
$scope.data = { sum: ... };
Here's a demonstration of your snippet with some amendments to make it work.

Related

How to pass different id's while using ng-repeat to an ng-click function

This is my HTML code.In this i am taking multiple values from ng-repeat and for each value i want the respective button to show and hide two div elements.In my web page , the buttons from different member blocks are working to show/hide only the first member block... The button with id=round should toggle btw div elements with id= first and id= second for all members that i get through ng-repeat.
<section id="team">
<div ng-controller="teamController as tctrl">
<div class="container">
<div class="row">
<div class="col-md-3 bord" ng-repeat="member in tctrl.members">
<button id="round" ng-click="showHide($index)">
<img id="direction" src="img/icon/uparrow.png">
</button>
<img ng-src="{{member.image}}">
<div id="first" class="memberabout" >
<h3 ng-bind="member.title"></h3>
<h2 ng-bind="member.name"></h2>
</div>
<div id="second" class="hid" >
<p ng-bind="member.about"></p>
</div>
</div>
</div>
</div>
</div>
</section>
and this is the js function i am trying to use:
$scope.showHide = function(index) {
if (document.getElementById('first') !== undefined) {
if (document.getElementById('first').style.display == 'none') {
document.getElementById('first').style.display = 'block';
document.getElementById('second').style.display = 'none';
var down = document.getElementById('round');
down.style.top = "201px";
var direction = document.getElementById('direction');
direction.src = 'img/icon/uparrow.png';
} else {
document.getElementById('first').style.display = 'none';
document.getElementById('second').style.display = 'block';
var down = document.getElementById('round');
down.style.top = "71px";
var direction = document.getElementById('direction');
direction.src = 'img/icon/arrowdown.png';
}
}
};
How should I pass the id's so that each button works to show/hide the div elements in their block?
Angularjs has many options to cancle using jQuery in your applications; options like modeling, directive and etc...
In your case you didn't need to use id because when we use ng-repeat in fact all of items are unique, so we just use them to show/hide or many other option you can do with object in the ng-repeat.
I hope this sample helps you to figure out how to use it:
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
var main = this;
main.members = [{
image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR4f5PCRqcMgg_KHymC29ABsy-PDFI08mb6qHqMviqbDDHjjuYM9g",
title: "A",
name: "jack",
about: "Hello World"
},
{
image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAxySZHmSrUU1_iIFJHGdDTdmTCAE610QnPwptWGWbMRAbSUzgNA",
title: "B",
name: "philip",
about: "Hello World 2"
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div ng-app="app" ng-controller="ctrl as tctrl">
<section id="team">
<div class="container">
<div class="row">
<div class="col" ng-repeat="member in tctrl.members">
<small>this is unique id if you want to use it: <b>id_{{$index}}</b> </small>
<div class="card">
<button ng-click="member.show = !member.show">
show/hide
</button>
<img ng-src="{{member.image}}">
<div ng-hide="member.show">
<h3 ng-bind="member.title"></h3>
<h2 ng-bind="member.name"></h2>
</div>
<div ng-show="member.show">
<p ng-bind="member.about"></p>
</div>
</div>
</div>
</div>
</div>
</section>
</div>

How to manipulate numeric values of some html tags and return new value instantly?

im new to js and im trying to manipulate values of some h4 and some other tags then do some little math on each and return the new value back to the tag.
thanks to #drydenlong & #oliverong i was able to achieve this so far:
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="input-group input-group-lg">
<span class="input-group-addon">Discount</span>
<input class="discount" type="text" placeholder="eg 30.22">
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="product">
<h2>Product 1</h2>
<h4 class="maththis">100</h4>
</div>
</div>
<div class="col-md-4">
<div class="product">
<h2>Product 2</h2>
<h4 class="maththis">200</h4>
</div>
</div>
<div class="col-md-4">
<div class="product">
<h2>Product 3</h2>
<h4 class="maththis" id="total">300</h4>
</div>
</div>
</div>
and this basic js
$('.discount').on('input',function(){
var base = parseInt($('.maththis').html());
var dis = $('.discount').val();
var newsum = dis - base;
$('.maththis').text(newsum);
});
i ran into some troubles and got stucked now :(
1) the calculation happens on keydown and that changes the values instantly, so there is also no going back. no new calculation possible unless relaoding page.
2) since im trying to change more values at once i also need to handle global variables i guess because in this example the value of text(). adds just the strings of the variable maththis toghether instead of each. so it makes 100 + 200 + 300= 100200300. this miscalculation gives also a NaN back.
how can i fix it so that the calculation happens on each class="maththis" seperatly and not together and how can i fix the value problem of class="maththis", so that i keep the original value somewhere incase i need to make changes on the discount value?
PEN: https://codepen.io/vup/pen/RxKjrw
PEN click function: https://codepen.io/vup/pen/Qadaqz
thanks alot <3
.text() will get you what is inside of the h1 element, so something like this will return 100:
var h1Val = $(".maththis").text();
Then you can use val() on whatever input field you have to do the math. In your case, it would be something like this:
var discount = $(".discount").val();
var h1Val = $(".maththis").text();
var total = h1Val - discount;
//Do whatever you need with the result
Here is a working example:
$('.discount').on('input',function(){
var base = $('.maththis').text();
var dis = $('.discount').val();
var total = base - dis;
$('#total').text('Total: '+total);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="discount" type="text" />
<h1 class="maththis">100</h1>
<span id="total"></span>
In javascript:
let num = +document.getElementsByTagName('h1')[0].innerText
In jquery:
let num = +$('h1').text();

Using AngularJS to show divs based on select value

I'm trying to use an HTML select element's value to show or hide certain div tags with AngularJS. Here is my code:
<body ng-app="kiosk" id="ng-app" >
<div class="page" ng-controller="kiosk-controller" ng-cloak="true">
<section class="signin">
<div class="intro">
<h1 id="service-desk-name">{{servicedeskname}}</h1><br></br>
<h4 id="welcome">{{welcome}}</h4>
</div>
<hr></hr>
<form id="form" name="form">
<div>
<label>Do you have an ID?</label><br></br>
<select type="select"
ng-model="user.affiliated"
ng-required="true"
ng-options="opt as opt.name for opt in affiliate.affiliateOptions">
<option value="">--Select an answer--</option>
</select>
</div>
<div ng-switch="user.affiliated">
<div ng-switch-when="Yes">
<!--><-->
</div>
<div ng-switch-when="No">
<!--><-->
</div>
</div>
And here is the Javascript snippet:
var kiosk = angular.module('kiosk',[]);
kiosk.controller('kiosk-controller', ['$scope', function($scope, $user) {
$scope.servicedeskname = 'Service Desk';
$scope.welcome = 'Please sign in and a consultant will be with you shortly.';
$scope.affiliate = {affiliateOptions:[]};
$scope.affiliate.affiliateOptions = [
{ name: 'Yes' },
{ name: 'No' }
];
/*other stuff*/
};
I can't figure out the proper way to reference the select options in the HTML tags using ng directives. Unless it's not super clear, I want to be able to show one div if the select value is "Yes", and show another if the select value is "No".
I think the switch statement you use need small modification
<div ng-switch on="user.affiliated">
<div ng-switch-when="Yes">
<!--><-->
</div>
<div ng-switch-when="No">
<!--><-->
</div>
</div>
check this ng-switch documentation for more help
I believe you're looking for ng-show and ng-hide.
<div ng-show="user.affiliated === 'Yes'"></div>
<div ng-show="user.affiliated === 'No'"></div>
And try changing this line to this:
ng-options="opt.name as opt.name for opt in affiliate.affiliateOptions">
You forgot the name property in the switch statement.
- <div ng-switch="user.affiliated">
+ <div ng-switch="user.affiliated.name">
As can be viewed in jsfiddle
you just have a little mistake. you must have user.affiliated.name instead of user.affiliated
like this
<div ng-switch="user.affiliated.name">
<div ng-switch-when="Yes">
yes
</div>
<div ng-switch-when="No">
no
</div>
</div>

AngularJS: How to prevent "code flash" in page while loading

I have created a simple app using AngularJS. When I open the page for a second I see the screen below:
However, after the load is complete I see the loaded and styled content which is fine:
How do I prevent the flash of AngularJS code on my page ? Is this related to FOUC ?
Here is the HTML code:
<!doctype html>
<html class="no-js" lang="en" ng-app="MainApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Foundation | Welcome</title>
<link rel="stylesheet" href="css/foundation.css" />
<script src="js/vendor/modernizr.js"></script>
<style>
.row.full-width {
width: 100%;
margin-left: auto;
margin-right: auto;
max-width: initial;
}
</style>
</head>
<body ng-controller="MainCtrl">
<div class="off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="tab-bar">
<section class="right-small">
<a class="right-off-canvas-toggle menu-icon" href="#"><span></span></a>
</section>
<section class="left tab-bar-section">
<h1 class="title">Salary Calculator</h1>
</section>
</nav>
<aside class="right-off-canvas-menu">
<ul class="off-canvas-list">
<li>
<label>Location</label>
</li>
<li>United Kingdom
</li>
</ul>
</aside>
<section class="main-section">
<div class="row full-width">
<div class="large-4 columns">
<ul class="tabs" data-tab>
<li class="tab-title active">Annual Salary
</li>
<li class="tab-title">Monthly Expenses
</li>
</ul>
<div class="tabs-content">
<div class="content active" id="panel1">
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Salary" ng-model="salary"/>
</div>
</div>
</div>
<div class="content" id="panel2">
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Rent" ng-model="rent" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Wireless, TV, Home Phone" ng-model="telecom"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="TV License" ng-model="tv" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Mobile Phone" ng-model="mobile"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Subscription" ng-model="subscription"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Electricty" ng-model="electricity" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Food" ng-model="food"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Transport" ng-model="transport" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Charity" ng-model="charity"/>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Other" ng-model="other"/>
</div>
</div>
</div>
</div>
</div>
<div class="large-8 columns" ng-cloak >
<table >
<thead>
<tr>
<th width="200"></th>
<th width="250">Yearly</th>
<th width="250">Monthly</th>
<th width="250">Weekly</th>
<th width="250">Daily</th>
</tr>
</thead>
<tbody ng-repeat="val in results">
<tr>
<td>{{val.rowType}}</td>
<td>{{val.yearly}}</td>
<td>{{val.monthly}}</td>
<td>{{val.weekly}}</td>
<td>{{val.daily}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<a class="exit-off-canvas"></a>
</div>
</div>
<script src="../bower_components/angularjs/angular.js"></script>
<script src="js/app-service.js"></script>
<script src="js/app-controller.js"></script>
<script src="js/app-directives.js"></script>
<script src="js/app.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
</body>
</html>
EDIT:
Please see my answer as well for an alternative solution in addition to the accepted one.
ng-cloak will help to some extent, but you can fully prevent it using ng-bind directive instead of using {{ }}.
e.g.
<td ng-bind="val.monthly"> </td>
not
<td>{{val.monthly}}</td>
It has been a long time but here is for my working solution for this one:
You need to use ng-cloak on the body tag of your html BUT the most important part is this CSS below:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
For me I had to add this for getting ng-cloak to work. This is probably not the only solution to this problem as can be seen in other answers. Hope this helps someone.
Angular already gives you the tool to prevent this: ngCloak: https://docs.angularjs.org/api/ng/directive/ngCloak
Just put the directive on your body like <body ng-cloak> and it should work.
EDIT
The Docs also advice you to actually not put it on the body, but on smaller portions of your page - wherever you see the need. Depending on the size of your page, that is a good idea. For smaller Pages I put it on the body and never had problems.
Along with ng-cloak, you can use a resolve object in your router. This will prevent the controller from instantiating and the view from rendering until the data is there.
In the following example I am assuming you are using uiRouter. The same pattern applies for ngRouter.
Your state config:
$stateProvider
.state('yourState',{
templateUrl: 'yourTemplate.html',
controller: 'YourController as vm',
resolve: YourController.resolve
})
As you can see, you have set the resolve property of the state to a static resolve object on your controller. Now the route will not resolve until this object is resolved.
To setup resolve object, lets assume you have a service yourService that has a method getData that returns a promise. This is very important. Because we don't want the route resolved until the promise is resolved.
So your controller may look something like this.
YourController.$inject = ['yourService'];
function YourController(yourService) {
var self = this;
yourService.getData().then((data) { self.data = data});
}
This is pretty standard. You can access the data from the view with vm.data but you will see a flash of {{vm.data}}. That is, if we remove the resolve we have added to the state config.
So now we change the controller to add a static resolve object to work with the resolve we have added to the state config.
YourController.resolve = {
'yourService': 'yourService',
'data': ['yourService', function(yourService) {
return yourService.getData();
}]
}
YourController.$inject = ['data'];
function YourController(data) {
this.data = data;
}
So now we have a resolve object. The yourService will resolve as a normal service, but the data property will resolve only when the promise returned by getData() is resolved. Then this data will be passed directly into the controller using Dependancy Injection.
In reality, you probably wont need to use ng-cloak if you use resolve.
Here is a working example:
angular.module('app', ['ui.router'])
.config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state('noDot', {
controller: "NoDotController",
template: "Using a old style $scope binding {{customers[0].CutomerName}}"
})
.state('noResolve', {
controller: "NoResolveController as vm",
template: "We are displaying things before the data is here {{vm.customers[0].CustomerName}}"
})
.state('withResolve', {
controller: "WithResolveController as vm",
template: "We are waiting for data before displaying anything {{vm.customers[0].CustomerName}}",
resolve: WithResolveController.resolve
})
.state('empty', {
template: ""
})
}
])
.controller('NoResolveController', NoResolveController)
.controller('NoDotController', NoDotController)
.controller('WithResolveController', WithResolveController)
.service('northwind', Northwind);
NoDotController.$inject = ['$scope', 'northwind'];
function NoDotController($scope, northwind) {
northwind.getCustomers().then(function(customers) {
$scope.customers = customers});
}
NoResolveController.$inject = ['northwind'];
function NoResolveController(northwind) {
var self = this;
northwind.getCustomers().then(function(customers) {
self.customers = customers;
});
}
WithResolveController.resolve = {
'northwind': 'northwind',
'customers': ['northwind',
function(northwind) {
return northwind.getCustomers();
}
]
}
WithResolveController.$inject = ['customers'];
function WithResolveController(customers) {
this.customers = customers;
}
Northwind.$inject = ['$timeout', '$q'];
function Northwind($timeout, $q) {
this.$q = $q;
this.$timeout = $timeout;
}
Northwind.prototype.getCustomers = function() {
var deferred = this.$q.defer();
this.$timeout(function() {
deferred.resolve([{CustomerName: "Name of Customer"}])
}, 1000);
return deferred.promise;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.js"></script>
<div ng-app="app">
<a ui-sref="noDot" href="#">No Dot</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="noResolve" href="#">No Resolve</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="withResolve" href="#">With Resolve</a>
<br>
<br>
<ui-view></ui-view>
</div>

Unable to use $.after() to close a div tag

This problem is best illustrated by example:
http://jsbin.com/lavonexuse
The desired effect is for clicking "Insert Row" to insert a full-width row after the indicated column (indicated by the class .insertion-point). The problem I'm running into is that instead of closing the current row first, and starting a new one, it just embeds a new row within the main row.
How do I close out the current row after any given column, make a new row, close that one, then resume showing the "data" columns?
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
<button class="btn btn-primary insert-row">Insert Row</button>
</body>
</html>
CSS:
.item {
border: 1px solid #f00;
}
.pane {
background: #999;
height: 100px;
}
JavaScript:
$('.insert-row').on('click', function() {
code = '</div><!--end row--><div class="row"><div class="col-sm-12 pane"></div></div>';
$('.insertion-point').after(code);
});
EDIT:
The code string above probably should end with <div class="row"> to re-open the row. But I tried that and it still doesn't work.
The problem here is that visually it looks like my solution works. Though in reality, it's creating bad HTML.
Further explanation (I think this is hard to explain). Here is what's happening, and this is NOT what I want:
I need that inserted row to be at the same level as the row it was erroneously inserted into.
Desired HTML after jQuery manipulation
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
</div>
<div class="row">
<div class="col-sm-12 pane"></div>
</div>
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
Further Ramblings
Maybe, since this is Bootstrap, there's some way I can use the grid system to have the same effect.
The code below should resolve your issue. Check out the code snippet and demo:
$('.insert-row').on('click', function() {
var row = $('<div/>',{class:"row"}),
code = '<!--end row--><div class="row"><div class="col-sm-12 pane">New</div></div>',
rest = $('.insertion-point').nextAll(),
dest = $('.insertion-point').closest('.row');
dest.after( row.append( rest ) ).after( code );
});
<script src="//code.jquery.com/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
<button class="btn btn-primary insert-row">Insert Row</button>
i worked out this four you: JsFiddle
$(document).ready(function() {
var firstRow = $('.row');
$('.insert-row').on('click', function() {
var code = $('<div/>', {clas: 'row'}).append($('<div/>', {class: "col-sm-12 pane"})),
row = $('<div/>', {class: 'row'}),
items = $('.insertion-point').nextAll();
row.append(items);
firstRow.after(row);
firstRow.after(code);
});
});
Update:
after seen the nextAll function by jQuery .. this will be much faster:
updated fiddle
I think what you need is appendTo which will append html onto the specified tag. In this case you want to append a div onto your row.
http://api.jquery.com/appendto/
Just get rid of the closing tag in the code variable and your code will work and be well formed
code = '</div><!--end row--><div class="row"><div class="col-sm-12 pane"></div></div>';
should be
code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
Also you need to insert rows after / before other rows like so
$('.insert-row').on('click', function() {
code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
$('.insertion-point').closest(".row").after(code);
});
The above code finds where you want to insert (which I changed to be an id selector since you want to insert after one unique element). However you want to find the closest parent element (or this one) that is a row so that you insert a row after that row. This way you can choose a row or a column to insert after and it will always insert a row after the closest row properly.
Lucky for you browsers are very forgiving when it comes to syntax errors in HTML. They will remove the initial closing tag (which is unnecessary) and use the rest of your HTML. But some browser may behave differently and that is what you have to be careful of.
You need to add a new row after the first by removing the elements after the insertion point and including them in the new row.
You can't treat the DOM like a text editor when inserting html.
$('.insert-row').on('click', function() {
var $insertEL=$('.insertion-point');
var code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
/* create new row and append all siblings after insertion point element*/
var $newRow=$(code).append($insertEL.nextAll());
/* add new row to DOM*/
$insertEL.closest('.row').after($newRow);
});
DEMO
Got it!
Layout solved by using Bootstrap grid, very little jQuery DOM manipulation. I don't know why I didn't think of this earlier. Sheesh. I've been coding for hours non-stop, my brain is fried.
Solution: http://jsbin.com/zopiquzore
This is correct, yes?

Categories

Resources