jQuery Mobile & AngularJS checkboxes horizontal - angularjs

Using jQuery Mobile and AngularJS together, without a plug-in but having read about it, loading jQuery first, and the two frameworks are mostly playing very nicely and quite powerful having both.
Trying to render jQuery Mobile checkboxes with
<div data-role="fieldcontain">
<legend>Showing more lodges slows the display</legend>
<fieldset data-role="controlgroup" data-type="horizontal">
<label ng-repeat-start="(lodgekey, lodge) in data.lodges" for="chooser_{{lodgekey}}">{{lodge.lodgetitle}}</label>
<input ng-repeat-end id="chooser_{{lodgekey}}" type="checkbox" ng-model="lodge.selected" />
</div>
</fieldset>
</div>
Problem is that jQuery Mobile finishes setting up the checkbox as a button prior to Angular doing the repeat. So the repeated checkboxes stack up vertically even though I have used data-type="horizontal" in the fieldset, and each show as first/last orphan - which they are before AngularJS does its ngRepeat. Viewing the code example at http://demos.jquerymobile.com/1.0a4.1/docs/forms/forms-checkboxes.html and looking at the rendered DOM shows the way it should render.

My solution so far has been to reproduce the jQuery Mobile form using Angular, but this is not ideal, here is my code:
<div data-role="fieldcontain" id="lodge-chooser">
<legend>Showing more lodges slows the display</legend>
<fieldset data-role="controlgroup" data-type="horizontal" class="ui-corner-all ui-controlgroup ui-controlgroup-horizontal">
<div class="ui-checkbox" ng-repeat="(lodgekey, lodge) in data.lodges">
<label ng-class="{'ui-btn-active':lodge.selected, 'ui-corner-left':$first, 'ui-corner-right':$last}" for="{{lodgekey}}">{{lodge.lodgetitle}}</label>
<input id="{lodgekey}}" type="checkbox" ng-model="lodge.selected" />
</div>
</fieldset>
</div>
and CSS:
/* remove incorrect rounded corners which appear on all buttons*/
div#lodge-chooser label.ui-btn.ui-corner-all {
border-radius:0!important;
}
/* reinstate rounded corners in correct places */
div#lodge-chooser label.ui-btn.ui-corner-left {
border-bottom-left-radius:inherit!important;
border-top-left-radius:inherit!important;
}
div#lodge-chooser label.ui-btn.ui-corner-right {
border-bottom-right-radius:inherit!important;
border-top-right-radius:inherit!important;
}
This works, noting that the div.ui-checkbox is nested redundantly because jQuery Mobile still adds it in but my addition provides the styles needed and the extra nested div doesn't appear to do any harm.

Related

Struts2 <s:checkbox> with 'value="true" not rendered as preselect if has Angular `ng-model`

I have observed a very peculiar behavior of <s:checkbox> rendering along with Bootstrap 3 and AngularJS.
I have these two <s:checkbox> in my page, wrapped by some elements of Bootstrap 3 styles:
<div class="col-md-1">
<div class="form-group">
<div class="form-other">
<label for="activaCheck"><s:text name="actividad.busqueda.activa"/></label>
<s:checkbox class="form-control" id="activaCheck" name="activaCheck" ng-model="formData.activaCheck" value="true"></s:checkbox>
<s:checkbox class="form-control" id="activaCheck2" name="activaCheck2" value="true"></s:checkbox>
</div>
</div>
</div>
As you can see, the only difference between them, is that the first has attribute ng-model = "xxx", while the second doesn't.
And, in my page, they are rendered differently, although they both are supposed to be pre-selected, because I set value="true". And when we inspect in FF, we can see the first <s:checkbox> has checked="checked", but is not rendered. I have tested in Chrome and FF, same.
I have also tested with <input type="checkbox" /> with ng-model set and checked="checked", the same: not checked when rendered in page.
So I am thinking about AngularJS is taking over part of rendering job which Struts 2 is responsible of, at least in this case. I want some explanation from developers of AngularJS, or this is the expected result?
I got the problem with unchecked checkbox. Because it has ng-model attribute the input control is bound to Angular's $scope. And if the scope doesn't define the property value for the above named checkbox it's not checked. Assumed that AngularJS modifies DOM as soon as it initializes.
I have created plnkr to demonstrate it.
You are right AngularJS starts working after document is loaded. At this time Struts has already done its work and returned html document to the browser. Now Angular continues to prepare the page to work only on one page. Both complement each other, but if Struts use to render
<input type="checkbox" ng-model="checkboxModel.value1" checked="checked">
Angular removes the checked state, because the value is commented
angular.module('checkboxExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.checkboxModel = {
//value1 : true,
value2 : 'YES'
};
}]);

Angular show-hide flickers

I'm switching the visibility of 2 elements when clicking them. A very simple use case:
<div ng-hide="filtersOpened"
ng-click="filtersOpened=true">
filters (opened)
</div>
<div ng-show="filtersOpened"
ng-click="filtersOpened=false">
filters (closed)
</div>
The change happens, but it flickers so that for a very short moment I see both elements together.
How can I make the change behave nicer, smoother, without the flickering? I've read about ng-cloack but doesn't seem like it's related since I'm not using a template.
Maybe try ng-if instead:
<div ng-if="filtersOpened" ng-click="filtersOpened=true">
filters (opened)
</div>
<div ng-if="!filtersOpened" ng-click="filtersOpened=false">
filters (closed)
</div>

Dropdown item text in AngularJS, bootstrap gets chopped from bottom

My dropdown has several values, when clicks on dropdown to see the list, grey has full 'y'. Upon selection, bottom portion of Grey gets chopped. This is happening with all similar characters.
Edit:
<div class="col-lg-6"><div class="col-lg-6">
<div class="form-group" ng-repeat="attrib in col1Attribs">
<div ng-class="invalidCodeClass">
<label class="control-label" for="txtCode">{{attrib.displayText}}</label>
<select id="ddl{{attrib.configType}}" class="form-control">
<option ng-repeat="c in configOptions(attrib.configType)" value="{{c.configId}}">{{c.configValue}}</option>
</select>
</div>
</div>
</div>
I don't think the problem is in your html or js code but rather with the css applied by the particular browser with which you are viewing the page.
Try changing the (font) styling on the select list; some suggestions:
1. reducing font size
2. increase line-height on select
3. removing styling options on select as #yuujin has suggested.
Probably with one of those changes you will be able to resolve the issue.

Expanding tiles layout using Angular in responsive layout

I'm developing an Angular single-page app with a responsive layout. The current page I'm working on uses a tile-based layout that auto wraps extra tiles to the next row. The HTML is below and, in the responsive layout, it can show 1, 2, or 3 tiles per row depending on the width of the row (it positions them using floats).
<div class="tiled_panel">
<div class="tile_1">...</div>
<div class="tile_2">...</div>
<div class="tile_3">...</div>
<div class="tile_4">...</div>
<div class="tile_5">...</div>
...
</div>
Now each tile will be given a "Learn More" button. The design calls for a block to expand between the row of the selected tile and the row below. This block will be the full width of the row and will be closed when the user closes it or clicks on a different Learn More button.
My first thought was to arrange the HTML as below using ng-if to hide or display the expander divs but I can't figure out the CSS needed to have it display between the rows.
<div class="tiled_panel">
<div class="tile_1">...</div>
<div class="expander_1">...</div>
<div class="tile_2">...</div>
<div class="expander_2">...</div>
<div class="tile_3">...</div>
<div class="expander_3">...</div>
<div class="tile_4">...</div>
<div class="expander_4">...</div>
<div class="tile_5">...</div>
<div class="expander_5">...</div>
...
</div>
My second thought, since I'm using Angular, was to somehow use transcluding or including to insert the relevant HTML into the appropriate spot. Again, I can't figure out how to identify where I need to insert the HTML?
I've tried searching around for other people's solutions to similar problems since I figured its not that unusual a requirement but I haven't yet been able to find anyone else who is doing this.
Can anyone else suggest what I need to do to identify the where to insert the HTML or how to generate the CSS? Or even suggest another solution that I haven't considered yet?
Although I have 70% understand of what you mean, I think ng-class can simply solve what you've faced. The solution code is like below. And I setup jsfiddle.
Html looks like this.
<div ng-app="" ng-controller="MyCtrl">
<div class="tiled_panel">
<div>Tile 1 <a href ng-click="change_tile(1)">More</a></div>
<div class="expander" ng-class="{'close': opentile===1}">Expander 1<a href ng-click="change_tile(-1)">Close</a></div>
<div>Tile 2 <a href ng-click="change_tile(2)">More</a></div>
<div class="expander" ng-class="{'close': opentile===2}">Expander 2<a href ng-click="change_tile(-2)">Close</a></div>
</div>
</div>
Your controller code looks like this.
$scope.change_tile = function(value){
$scope.opentile = value;
}
$scope.change_tile(0);
Css looks like this.
.expander{
visibility: hidden
}
.close{
visibility: visible
}

How to disable content based on checkbox in AngularJS/Bootstrap3

I am creating a form where the user can configure a recurring event, so there are a large number of controls. At the top is a checkbox to enable/disable the schedule.
How can I disable, but not hide, the entire section based on the checkbox? If it is checked, the user should be able to make modifications to the schedule. If it is not checked, no changes should be allowed.
I'm fairly certain I can use the ng-disabled directive on each control, but I'd like to set some attribute/class on the entire container, rather than on each individual control.
I am using Bootstrap 3, so if there is a class that would provide this functionality, that would be an acceptable solution as well.
Here is the relevant section of the HTML:
<input type="checkbox" ng-model="status" title="Enable/Disable Schedule" /> <b>Schedule the task to run:</b>
<div class="row"> <!-- need a way to disable this row based on the checkbox -->
<span>Every <input type="number" ng-model="interval" />
<select ng-model="frequency"
ng-options="freq as freq.name for freq in frequencies"></select>
</span>
<div>
On these days:
</div>
<div class="btn-group" data-toggle="buttons-checkbox">
<button type="button"
class="btn"
ng-model="day.value"
ng-repeat="day in days">{{day.name}}</button>
</div>
</div>
I have tried:
<div class="row" ng-disabled="!status">
It didn't work, and based on the docs, it doesn't look like it is even supposed to, as its intended use is for disabling form controls. I also tried without the !, just to validate that it wouldn't work either.
OK, I found a technique that works for my purposes...
<div class="row" ng-class="{disabled: !status}"> <!-- added ng-class here -->
and
.disabled {
z-index: 1000;
background-color: lightgrey;
opacity: 0.6;
pointer-events: none;
}
This prevents clicks on the page and gives a nice visual indication of the section being "disabled".
It does not prevent me from tabbing through the controls, but it works OK for my purposes.

Resources