2015-06-05 2 views
1

Я пытаюсь создать директиву для своего Углового, чтобы помочь с интеграцией полей формы. Я внедрил решение Скотта Алленса из своего Angular playbook, и он отлично работает для обычной уложенной формы.Угловая директива для горизонтальной формы бутстрапа

Мне нужно, однако, адаптировать его к горизонтальной форме. Вот мой код:

Markup

<div form-group> 
    <label for="name">Name</label> 
    <input type="text" id="name" ng-model="vm.name"> 
</div> 

formGroup директива

function link(scope, element) { 
    setupDom(element[0]); 
} 

function setupDom(element) { 
    var label = element.querySelector("label"); 
    label.classList.add("control-label"); 

    var input = element.querySelector("input, textarea, select"); 
    var type = input.getAttribute("type"); 
    if (type !== "radio" && type !== "checkbox"){ 
     input.classList.add("form-control"); 
    } 

    element.classList.add("form-group"); 
} 

function formGroup() { 
    return { 
     restrict: "A", 
     link: link 
    } 
} 

Выход становится:

<div form-group="" class="form-group"> 
    <label for="name" class="control-label">Name</label> 
    <input type="text" id="name" ng-model="vm.name" class="form-control"> 
</div> 

И это нормально для сложенной формы. Так как мне нужна горизонтальная форма, мой выход должен выглядеть следующим образом:

<div form-group="" class="form-group"> 
    <label for="name" class="control-label col-sm-3">Name</label> 

    <div class="col-sm-9"> 
     <input type="text" id="name" ng-model="vm.name" class="form-control"> 
    </div> 
</div> 

Я пробовал много решений, и я могу заставить его работать с отдельными элементами, как вход, или текстовое поле отборные. Это становится намного сложнее, когда у меня есть что-то вроде двух переключателей внутри моей разметке вроде этого:

<div form-group> 
    <label>Active</label> 

    <div class="radio"> 
     <label> 
      <input type="radio" name="active" ng-value="true" ng-model="vm.active"> Yes 
     </label> 
    </div> 
    <div class="radio"> 
     <label> 
      <input type="radio" name="active" ng-value="false" ng-model="vm.active"> No 
     </label> 
    </div> 
</div> 

Нужный выход указанного выше кода должно быть:

<div form-group class="form-group"> 
    <label class="control-label col-sm-3">Active</label> 

    <div class="col-sm-9"> 
     <div class="radio"> 
      <label> 
       <input type="radio" name="active" ng-value="true" ng-model="vm.active"> Yes 
      </label> 
     </div> 
     <div class="radio"> 
      <label> 
       <input type="radio" name="active" ng-value="false" ng-model="vm.active"> No 
      </label> 
     </div> 
    </div> 
</div> 

Пожалуйста, обратите внимание, что вход (s) в группе форм не фиксировано. Это может быть либо один вход, текстовое поле, выбор, группа переключателей или флажков. Я потерялся за то, как я могу это сделать. Любая помощь приветствуется. Благодаря!

UPDATE

Я сделал некоторые небольшие изменения в коде Марка Веенстра, чтобы сделать это (вроде) рабочий:

function setupDom(element) { 
    element.classList.add("form-group"); 

    var label = element.querySelector("label"); 
    label.classList.add("control-label", "col-sm-3"); 

    var input = element.querySelector("input, textarea, select"); 
    var type = input.getAttribute("type"); 
    if (type !== "radio" && type !== "checkbox"){ 
     input.classList.add("form-control"); 
     angular.element(input).wrap(angular.element('<div class="col-sm-9"></div>')); 
    } 

    var div_radio = element.querySelector("div[class='radio']"); 
    angular.element(div_radio).wrap(angular.element('<div class="col-sm-9"></div>')); 
} 

Это не работает полностью, как предполагалось с несколькими входами радио, так как ему только обертывает <div> на первый элемент радиовхода.

Выход из примера радиокнопки в моей должности, используя Marks коды:

<div form-group="" class="form-group"> 
    <label class="control-label col-sm-3">Active</label> 

    <div class="col-sm-9"> 
     <div class="radio"> 
      <label> 
       <input type="radio" name="active" ng-value="true" ng-model="vm.active" value="true"> Yes 
      </label> 
     </div> 
    </div> 
    <div class="radio"> 
     <label> 
      <input type="radio" name="active" ng-value="false" ng-model="vm.active" value="false"> No 
     </label> 
    </div> 
</div> 

РЕШЕНИЕ

ЗАКАНЧИВАТЬ Plunker с конечным результатом: http://plnkr.co/edit/Wv6V86hHTCz3URS9DhdU?p=preview

+0

Можете ли вы поделиться с plunker показывая ваши попытки достичь этого? Тогда будет легче увидеть, где вы ошибаетесь. –

+0

@AbhishekJain ознакомьтесь с этим [Plunker] (http://plnkr.co/edit/Wv6V86hHTCz3URS9DhdU?p=preview) для окончательного результата, если вам интересно – KlaasJan

ответ

1

В angular.elementdocumentation вы можете найти способ wrap(), чтобы иметь возможность обернуть HTML вокруг выбранного элемента. Или см. this прямая ссылка.

Так что вы можете сделать в своей директиве, это изменить функцию setupDom(), чтобы соответствовать вашим требованиям к типу элемента формы.

function link(scope, element) { 
    setupDom(element[0]); 
} 

function setupDom(element) { 
    element.classList.add("form-group"); 

    var label = element.querySelector("label"); 
    label.classList.add("control-label col-sm-3"); 

    var input = element.querySelector("input, textarea, select"); 
    var type = input.getAttribute("type"); 
    if (type !== "radio" && type !== "checkbox"){ 
     input.classList.add("form-control"); 
     input.wrap(angular.element('<div class="col-sm-9"></div>')); 
    } 

    var div_radio = element.querySelectorAll("div[class='radio']"); 
    div_radio.wrap(angular.element('<div class="col-sm-9"></div>')); 
} 

function formGroup() { 
    return { 
     restrict: "A", 
     link: link 
    } 
} 

Примечание: Этот код не проверял, может быть, есть некоторые незначительные ошибки, но я думаю, вы получите точку прямо сейчас.

+0

Благодарим вас за предложение @mark. Пожалуйста, взгляните на мой пост ниже. – KlaasJan

+0

Возможно, измените элемент element.querySelector ("div [class = 'radio']") 'to' element.querySelectorAll ("div [class = 'radio']") ' –

+0

попробовал, но он завернул каждую группу радио в ее собственный 'div'. Я обновил свой оригинальный вопрос с помощью решения и связался с Plunker. – KlaasJan

1

Предложение Марка приблизилось, но оно не решило мою проблему полностью. Я в конечном итоге, используя следующий код в моей директиве formGroup:

(function (module) { 
    "use strict"; 

    function link(scope, element) { 
     setupDom(element[0]); 
    } 

    function setupDom(element) { 
     element.classList.add("form-group"); 

     var children = angular.element(element).children(); 
     var labels = children.splice(0, 1); 

     // Set label classes 
     labels[0].classList.add("control-label", "col-sm-3"); 

     // Wrap children in div 
     angular.element(children).wrapAll(angular.element("<div class='col-sm-9'></div>")); 

     // Handle inputs 
     var inputs = element.querySelectorAll("input, textarea, select"); 
     for (var i = 0, len = inputs.length; i < len; i++) { 
      var input = inputs[i], 
       type = input.getAttribute("type"); 

      if (type !== "radio" && type !== "checkbox") { 
       input.classList.add("form-control"); 
      } 
     } 
    } 

    function formGroup() { 
     return { 
      restrict: "A", 
      link: link 
     } 
    } 

    module.directive("formGroup", formGroup); 

}(angular.module("app.core"))); 

Проверьте эту Plunker, чтобы увидеть его в действии: http://plnkr.co/edit/Wv6V86hHTCz3URS9DhdU?p=preview

Смежные вопросы