Javascript navigation and form data.

One of the things that I found myself doing over and over again was creating a function to post data back to the server so I created a tiny class that makes use of my jsfunction class to simplify the creation of post functions.

#include "jsnav.h"

using std::string;
using std::vector;

jsnav::jsnav(std::string fName)
    :
      jsfunction(build_function_name(fName))

{
    jsfunction::add_line("var form = document.createElement(\"form\");");
    jsfunction::add_line("form.setAttribute(\"method\", \"post\");");
    jsfunction::add_line("form.setAttribute(\"action\", doNext);");
    jsfunction::add_line_break();

}

string jsnav::build_function_name(string fName) {

    string fcn;
    if(fName.find_first_of("(") == std::string::npos)
        fcn = fName+"(doNext)";
    else {
        fcn = fName;
    }

    return(fcn);

}

void jsnav::build_js_function() {

    auto val = [](POST_DATA &cur)->string{
        return(
                (cur.literal) ?
                         "\""+cur.value+"\"" : cur.value
                );
    };

    auto nam = [&](POST_DATA &cur)->string {
        string name = m_fcnDeclaration.substr(
                    m_fcnDeclaration.find_first_of("("),
                    m_fcnDeclaration.find_last_of(")")
                    );
        return(
                    (name.find(cur.name) == std::string::npos) ?
                        "\""+cur.name+"\"" : cur.name
                        );
    };

    for(POST_DATA &it : m_postData) {
        string elementId = "FRM_" + it.name;
        jsfunction::add_line("var " + elementId + " = document.createElement(\"input\");");
        jsfunction::add_line(elementId+".setAttribute(\"type\", \"hidden\");");
        jsfunction::add_line(elementId+".setAttribute(\"name\", " + nam(it) + ");");
        jsfunction::add_line(elementId+".setAttribute(\"value\", " + val(it) + ");");
        jsfunction::add_line("form.appendChild(" + elementId + ");");
        jsfunction::add_line_break();
    }

    jsfunction::add_line("document.body.appendChild(form);");
    jsfunction::add_line("form.submit();");
}

void jsnav::add_attribute(std::string name, std::string value, bool literal) {
    m_postData.push_back( {name, value, literal} );
}


 

 

The constructor:

jsnav without any arguments will create a function called nav(doNext).

jsnav with a given name will create a function with that name i.e.

jsnav fcn("myfcn");

 

will create a function called myfcn(doNext).

jsnav with with a series of arguments will declare the function literally

jsnav fcn("myfcn(arg1, arg2, doNext");

 

Note that one of the arguments must always be doNext.

 

add_attribute(std::string name, std::string value, bool literal)

This is the method you call to set a given value when the method is called.

Name:

If the name is found in the function declaration then it will be treated as a variable, if not then it will be treated as a literal

Value:

The value can either be a literal value or something else such as a function call.  If it is a literal string then you do not need to pass a third argument as bool literal is automatically set to true. If it is a function call then you must set literal to false.

Theoretically this method can be called as many times as necessary.

When you are done adding attributes then you need to call build_js_function() in order to construct the function before calling js_function(int indent) to grab the string;