1

I working on a contact form. The point is it should be accessible without JavaScript. If JavaScript is avaible I want ask visitors about some details based on their purpose of contact.

HTML could look like this (labels are skipped on purpose, to shorten the code):

<form action="">
    <select name="purpose">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    ...
    <button>Submit</button>
</form>

Well, if I could I would just add some areas that would be shown based on "model". But I can't do it because I don't want to show additional fields to people without JS. It would be like this:

<form action="" ng-app>
    <select name="purpose" ng-model="purpose">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    ...
    <div ng-show="purpose == 'support'">
        <input type="text" name="customernumber" />
    </div>
    <div ng-show="purpose == 'interview'">
        Sorry, I'm not giving interviews
    </div>
    ...
    <button>Submit</button>
</form>

The point is that I will be asking a lot of additional questions. With JS disabled the visitor will be seeing a bloated contact form with all fields and messages.

I'm looking for a solution that would read the value of and inject HTML from JS file into a specific place.

<form action="" ng-app>
    <select name="purpose" ng-model="purpose">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    ...
    {{injectedHTML}}
    ...
    <button>Submit</button>
</form>

It sounds strange, but everything must be according to the requirements of local municipal office. They want to show these specific fields only to people with JS. Maybe they think it is good for accessibility. I'm not sure.

Thank you all.

2 Answers 2

3

To simply hide set of elements when JavaScript is disabled you could add ng-hide class to elements that should not be displayed. In example:

<form action="" ng-app>
    <select name="purpose" ng-model="purpose">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    ...
    <div ng-show="purpose == 'support'" class="ng-hide">
        <input type="text" name="customernumber" />
    </div>
    <div ng-show="purpose == 'interview'" class="ng-hide">
        Sorry, I'm not giving interviews
    </div>
    ...
    <button>Submit</button>
</form>

The ng-hide class sets display: hidden. When JavaScript is enabled ng-show will evaluate the condition and add or remove ng-hide class from element.

Another fairly simple solution would be to use ng-include to load additional content when appropriate - which obviously would only work when JavaScript is enabled - thus making additional fields hidden when JavaScript is not working.

<form action="" ng-app>
    <select name="purpose" ng-model="purpose">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    ...
    <div ng-if="purpose == 'support'" ng-include="'views/supportField.html'">
    </div>
    <div ng-if="purpose == 'interview'" ng-include="'views/interviewField.html'">
    </div>

    ...
    <button>Submit</button>
</form>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This would definitely work. But I was looking for solution that would be more elegant. Something with controllers.
1

Thanks to miensol I started to think about method using "ng-include". Then I realised one thing: Angular can override the HTML.

So I came with this HTML:

<form ng-controller="ContactController">
    <select ng-model="purpose" ng-options="p.title for p in possibilities track by p.value">
        <option value="hello">Just saying hi</option>
        <option value="support">Customer Support</option>
        <option value="interview">Interview</option>
    </select>
    <div ng-include="purpose.template"></div>
</form>

And this app.js:

(function(){
    var app = angular.module('myApp', []);

    app.controller('ContactController', ['$scope', function($scope) {

        // array with possible reasons, that we use as <option> in <select>
        // the "AJ" is added so you can see the difference
        $scope.possibilities =
            [
                { title: 'AJ Just saying hi', value='hello', template: 'part-support.html'},
                { title: 'AJ Customer Support', value='support', template: 'part-support.html'},
                { title: 'AJ Interview', value='interview', template: 'part-interview.html'}
            ];

        // select default <option>
        $scope.purpose = $scope.possibilities[0];

    }]);

})();

Still I got feeling it could be written much better (and it's out of my league).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.